@sundaeswap/sprinkles 0.6.1 → 0.8.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 (197) hide show
  1. package/README.md +178 -181
  2. package/dist/cjs/Sprinkle/__tests__/action-integration.test.js +590 -0
  3. package/dist/cjs/Sprinkle/__tests__/action-integration.test.js.map +1 -0
  4. package/dist/cjs/Sprinkle/__tests__/action-registry.test.js +193 -0
  5. package/dist/cjs/Sprinkle/__tests__/action-registry.test.js.map +1 -0
  6. package/dist/cjs/Sprinkle/__tests__/action-runner.test.js +304 -0
  7. package/dist/cjs/Sprinkle/__tests__/action-runner.test.js.map +1 -0
  8. package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js +1110 -0
  9. package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
  10. package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +744 -0
  11. package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
  12. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
  13. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  14. package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +711 -0
  15. package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
  16. package/dist/cjs/Sprinkle/__tests__/native-script.test.js +390 -0
  17. package/dist/cjs/Sprinkle/__tests__/native-script.test.js.map +1 -0
  18. package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js +334 -0
  19. package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
  20. package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js +367 -0
  21. package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
  22. package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js +749 -0
  23. package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
  24. package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js +164 -0
  25. package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
  26. package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js +61 -0
  27. package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
  28. package/dist/cjs/Sprinkle/actions/builtin/index.js +174 -0
  29. package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -0
  30. package/dist/cjs/Sprinkle/actions/builtin/native-script.js +139 -0
  31. package/dist/cjs/Sprinkle/actions/builtin/native-script.js.map +1 -0
  32. package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js +202 -0
  33. package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
  34. package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js +87 -0
  35. package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
  36. package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js +345 -0
  37. package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
  38. package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js +218 -0
  39. package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
  40. package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js +212 -0
  41. package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
  42. package/dist/cjs/Sprinkle/actions/cli-adapter.js +390 -0
  43. package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
  44. package/dist/cjs/Sprinkle/actions/index.js +139 -0
  45. package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
  46. package/dist/cjs/Sprinkle/actions/mcp-adapter.js +557 -0
  47. package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -0
  48. package/dist/cjs/Sprinkle/actions/registry.js +92 -0
  49. package/dist/cjs/Sprinkle/actions/registry.js.map +1 -0
  50. package/dist/cjs/Sprinkle/actions/runner.js +190 -0
  51. package/dist/cjs/Sprinkle/actions/runner.js.map +1 -0
  52. package/dist/cjs/Sprinkle/actions/tui-helpers.js +96 -0
  53. package/dist/cjs/Sprinkle/actions/tui-helpers.js.map +1 -0
  54. package/dist/cjs/Sprinkle/actions/types.js +68 -0
  55. package/dist/cjs/Sprinkle/actions/types.js.map +1 -0
  56. package/dist/cjs/Sprinkle/index.js +678 -5
  57. package/dist/cjs/Sprinkle/index.js.map +1 -1
  58. package/dist/cjs/Sprinkle/prompts.js +12 -7
  59. package/dist/cjs/Sprinkle/prompts.js.map +1 -1
  60. package/dist/cjs/Sprinkle/schemas.js +17 -1
  61. package/dist/cjs/Sprinkle/schemas.js.map +1 -1
  62. package/dist/cjs/Sprinkle/type-guards.js +7 -1
  63. package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
  64. package/dist/esm/Sprinkle/__tests__/action-integration.test.js +588 -0
  65. package/dist/esm/Sprinkle/__tests__/action-integration.test.js.map +1 -0
  66. package/dist/esm/Sprinkle/__tests__/action-registry.test.js +192 -0
  67. package/dist/esm/Sprinkle/__tests__/action-registry.test.js.map +1 -0
  68. package/dist/esm/Sprinkle/__tests__/action-runner.test.js +302 -0
  69. package/dist/esm/Sprinkle/__tests__/action-runner.test.js.map +1 -0
  70. package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +1107 -0
  71. package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
  72. package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +742 -0
  73. package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
  74. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
  75. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  76. package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +710 -0
  77. package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
  78. package/dist/esm/Sprinkle/__tests__/native-script.test.js +388 -0
  79. package/dist/esm/Sprinkle/__tests__/native-script.test.js.map +1 -0
  80. package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js +332 -0
  81. package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
  82. package/dist/esm/Sprinkle/__tests__/utility-actions.test.js +365 -0
  83. package/dist/esm/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
  84. package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js +747 -0
  85. package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
  86. package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js +159 -0
  87. package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
  88. package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js +55 -0
  89. package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
  90. package/dist/esm/Sprinkle/actions/builtin/index.js +37 -0
  91. package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -0
  92. package/dist/esm/Sprinkle/actions/builtin/native-script.js +133 -0
  93. package/dist/esm/Sprinkle/actions/builtin/native-script.js.map +1 -0
  94. package/dist/esm/Sprinkle/actions/builtin/profile-actions.js +197 -0
  95. package/dist/esm/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
  96. package/dist/esm/Sprinkle/actions/builtin/settings-actions.js +81 -0
  97. package/dist/esm/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
  98. package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js +340 -0
  99. package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
  100. package/dist/esm/Sprinkle/actions/builtin/utility-actions.js +213 -0
  101. package/dist/esm/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
  102. package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js +207 -0
  103. package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
  104. package/dist/esm/Sprinkle/actions/cli-adapter.js +379 -0
  105. package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -0
  106. package/dist/esm/Sprinkle/actions/index.js +12 -0
  107. package/dist/esm/Sprinkle/actions/index.js.map +1 -0
  108. package/dist/esm/Sprinkle/actions/mcp-adapter.js +547 -0
  109. package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -0
  110. package/dist/esm/Sprinkle/actions/registry.js +85 -0
  111. package/dist/esm/Sprinkle/actions/registry.js.map +1 -0
  112. package/dist/esm/Sprinkle/actions/runner.js +182 -0
  113. package/dist/esm/Sprinkle/actions/runner.js.map +1 -0
  114. package/dist/esm/Sprinkle/actions/tui-helpers.js +91 -0
  115. package/dist/esm/Sprinkle/actions/tui-helpers.js.map +1 -0
  116. package/dist/esm/Sprinkle/actions/types.js +61 -0
  117. package/dist/esm/Sprinkle/actions/types.js.map +1 -0
  118. package/dist/esm/Sprinkle/index.js +517 -7
  119. package/dist/esm/Sprinkle/index.js.map +1 -1
  120. package/dist/esm/Sprinkle/prompts.js +12 -7
  121. package/dist/esm/Sprinkle/prompts.js.map +1 -1
  122. package/dist/esm/Sprinkle/schemas.js +16 -0
  123. package/dist/esm/Sprinkle/schemas.js.map +1 -1
  124. package/dist/esm/Sprinkle/type-guards.js +3 -0
  125. package/dist/esm/Sprinkle/type-guards.js.map +1 -1
  126. package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts +50 -0
  127. package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts.map +1 -0
  128. package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts +39 -0
  129. package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts.map +1 -0
  130. package/dist/types/Sprinkle/actions/builtin/index.d.ts +30 -0
  131. package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -0
  132. package/dist/types/Sprinkle/actions/builtin/native-script.d.ts +27 -0
  133. package/dist/types/Sprinkle/actions/builtin/native-script.d.ts.map +1 -0
  134. package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts +55 -0
  135. package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts.map +1 -0
  136. package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts +32 -0
  137. package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts.map +1 -0
  138. package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts +70 -0
  139. package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts.map +1 -0
  140. package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts +48 -0
  141. package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts.map +1 -0
  142. package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts +50 -0
  143. package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts.map +1 -0
  144. package/dist/types/Sprinkle/actions/cli-adapter.d.ts +104 -0
  145. package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -0
  146. package/dist/types/Sprinkle/actions/index.d.ts +13 -0
  147. package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
  148. package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +116 -0
  149. package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -0
  150. package/dist/types/Sprinkle/actions/registry.d.ts +42 -0
  151. package/dist/types/Sprinkle/actions/registry.d.ts.map +1 -0
  152. package/dist/types/Sprinkle/actions/runner.d.ts +45 -0
  153. package/dist/types/Sprinkle/actions/runner.d.ts.map +1 -0
  154. package/dist/types/Sprinkle/actions/tui-helpers.d.ts +53 -0
  155. package/dist/types/Sprinkle/actions/tui-helpers.d.ts.map +1 -0
  156. package/dist/types/Sprinkle/actions/types.d.ts +76 -0
  157. package/dist/types/Sprinkle/actions/types.d.ts.map +1 -0
  158. package/dist/types/Sprinkle/index.d.ts +84 -2
  159. package/dist/types/Sprinkle/index.d.ts.map +1 -1
  160. package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
  161. package/dist/types/Sprinkle/schemas.d.ts +72 -0
  162. package/dist/types/Sprinkle/schemas.d.ts.map +1 -1
  163. package/dist/types/Sprinkle/type-guards.d.ts +4 -1
  164. package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
  165. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  166. package/package.json +9 -2
  167. package/src/Sprinkle/__tests__/action-integration.test.ts +558 -0
  168. package/src/Sprinkle/__tests__/action-registry.test.ts +187 -0
  169. package/src/Sprinkle/__tests__/action-runner.test.ts +324 -0
  170. package/src/Sprinkle/__tests__/builtin-actions.test.ts +1022 -0
  171. package/src/Sprinkle/__tests__/cli-adapter.test.ts +736 -0
  172. package/src/Sprinkle/__tests__/fill-in-struct.test.ts +23 -1
  173. package/src/Sprinkle/__tests__/mcp-adapter.test.ts +720 -0
  174. package/src/Sprinkle/__tests__/native-script.test.ts +341 -0
  175. package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
  176. package/src/Sprinkle/__tests__/utility-actions.test.ts +348 -0
  177. package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
  178. package/src/Sprinkle/actions/builtin/addressbook-actions.ts +168 -0
  179. package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
  180. package/src/Sprinkle/actions/builtin/index.ts +125 -0
  181. package/src/Sprinkle/actions/builtin/native-script.ts +165 -0
  182. package/src/Sprinkle/actions/builtin/profile-actions.ts +229 -0
  183. package/src/Sprinkle/actions/builtin/settings-actions.ts +99 -0
  184. package/src/Sprinkle/actions/builtin/transaction-actions.ts +381 -0
  185. package/src/Sprinkle/actions/builtin/utility-actions.ts +285 -0
  186. package/src/Sprinkle/actions/builtin/wallet-actions.ts +233 -0
  187. package/src/Sprinkle/actions/cli-adapter.ts +446 -0
  188. package/src/Sprinkle/actions/index.ts +33 -0
  189. package/src/Sprinkle/actions/mcp-adapter.ts +638 -0
  190. package/src/Sprinkle/actions/registry.ts +97 -0
  191. package/src/Sprinkle/actions/runner.ts +200 -0
  192. package/src/Sprinkle/actions/tui-helpers.ts +114 -0
  193. package/src/Sprinkle/actions/types.ts +91 -0
  194. package/src/Sprinkle/index.ts +612 -3
  195. package/src/Sprinkle/prompts.ts +118 -72
  196. package/src/Sprinkle/schemas.ts +20 -0
  197. package/src/Sprinkle/type-guards.ts +9 -0
@@ -61,7 +61,9 @@ interface SelectConfig<T> {
61
61
  theme?: PartialDeep<Theme<typeof selectTheme>>;
62
62
  }
63
63
 
64
- function isSelectable<T>(item: SelectChoice<T> | Separator): item is SelectChoice<T> {
64
+ function isSelectable<T>(
65
+ item: SelectChoice<T> | Separator,
66
+ ): item is SelectChoice<T> {
65
67
  return !Separator.isSeparator(item) && !item.disabled;
66
68
  }
67
69
 
@@ -100,7 +102,10 @@ export const selectCancellable = createPrompt<
100
102
  const { loop = true, pageSize = 15 } = config;
101
103
  const theme = makeTheme(selectTheme, config.theme);
102
104
  const [status, setStatus] = useState<"idle" | "done" | "cancelled">("idle");
103
- const prefix = usePrefix({ status: status === "cancelled" ? "done" : status, theme });
105
+ const prefix = usePrefix({
106
+ status: status === "cancelled" ? "done" : status,
107
+ theme,
108
+ });
104
109
 
105
110
  const items = useMemo(
106
111
  () => normalizeChoices(config.choices),
@@ -199,7 +204,9 @@ export const selectCancellable = createPrompt<
199
204
  return `${prefix} ${config.message} ${colors.cyan(selectedChoice?.short ?? selectedChoice?.name ?? "")}`;
200
205
  }
201
206
 
202
- const helpTip = colors.dim("(Use arrow keys, Enter to select, Esc to cancel)");
207
+ const helpTip = colors.dim(
208
+ "(Use arrow keys, Enter to select, Esc to cancel)",
209
+ );
203
210
  return `${prefix} ${config.message} ${helpTip}\n${page}`;
204
211
  });
205
212
 
@@ -291,7 +298,10 @@ export const inputCancellable = createPrompt<string | null, InputConfig>(
291
298
  const [touched, setTouched] = useState(false);
292
299
  const [error, setError] = useState<string | null>(null);
293
300
  const theme = makeTheme(inputTheme);
294
- const prefix = usePrefix({ status: status === "cancelled" ? "done" : status, theme });
301
+ const prefix = usePrefix({
302
+ status: status === "cancelled" ? "done" : status,
303
+ theme,
304
+ });
295
305
 
296
306
  useKeypress(async (key, rl) => {
297
307
  if (isEscapeKey(key)) {
@@ -356,7 +366,10 @@ export const passwordCancellable = createPrompt<string | null, PasswordConfig>(
356
366
  const [value, setValue] = useState("");
357
367
  const [error, setError] = useState<string | null>(null);
358
368
  const theme = makeTheme(inputTheme);
359
- const prefix = usePrefix({ status: status === "cancelled" ? "done" : status, theme });
369
+ const prefix = usePrefix({
370
+ status: status === "cancelled" ? "done" : status,
371
+ theme,
372
+ });
360
373
  const mask = config.mask ?? "*";
361
374
 
362
375
  useKeypress(async (key, rl) => {
@@ -418,7 +431,10 @@ export const confirmCancellable = createPrompt<boolean | null, ConfirmConfig>(
418
431
  // Track value as undefined when no default, requiring explicit y/n
419
432
  const [value, setValue] = useState<boolean | undefined>(config.default);
420
433
  const theme = makeTheme(inputTheme);
421
- const prefix = usePrefix({ status: status === "cancelled" ? "done" : status, theme });
434
+ const prefix = usePrefix({
435
+ status: status === "cancelled" ? "done" : status,
436
+ theme,
437
+ });
422
438
 
423
439
  useKeypress((key) => {
424
440
  if (isEscapeKey(key)) {
@@ -437,7 +453,12 @@ export const confirmCancellable = createPrompt<boolean | null, ConfirmConfig>(
437
453
  }
438
454
  });
439
455
 
440
- const hint = config.default === true ? "(Y/n)" : config.default === false ? "(y/N)" : "(y/n)";
456
+ const hint =
457
+ config.default === true
458
+ ? "(Y/n)"
459
+ : config.default === false
460
+ ? "(y/N)"
461
+ : "(y/n)";
441
462
  const displayValue = value === true ? "Yes" : value === false ? "No" : "";
442
463
 
443
464
  if (status === "cancelled") {
@@ -458,7 +479,9 @@ export const confirmCancellable = createPrompt<boolean | null, ConfirmConfig>(
458
479
  * Returns the selected value with proper typing, or null if cancelled.
459
480
  */
460
481
  export async function select<T>(config: SelectConfig<T>): Promise<T | null> {
461
- return selectCancellable(config as SelectConfig<unknown>) as Promise<T | null>;
482
+ return selectCancellable(
483
+ config as SelectConfig<unknown>,
484
+ ) as Promise<T | null>;
462
485
  }
463
486
 
464
487
  interface SearchConfig<T> {
@@ -475,77 +498,100 @@ interface SearchConfig<T> {
475
498
  * Note: This wraps @inquirer/search which has built-in escape handling,
476
499
  * but we provide a consistent API with other cancellable prompts.
477
500
  */
478
- export const searchCancellable = createPrompt<unknown | null, SearchConfig<unknown>>(
479
- (config, done) => {
480
- const [status, setStatus] = useState<"idle" | "done" | "cancelled">("idle");
481
- const [searchTerm, setSearchTerm] = useState("");
482
- const [results, setResults] = useState<{ name: string; value: unknown }[]>([]);
483
- const [active, setActive] = useState(0);
484
- const [loading, setLoading] = useState(false);
485
- const theme = makeTheme(selectTheme);
486
- const prefix = usePrefix({ status: status === "cancelled" ? "done" : status, theme });
487
-
488
- // Fetch results when search term changes
489
- useMemo(async () => {
490
- setLoading(true);
491
- try {
492
- const items = await config.source(searchTerm || undefined);
493
- setResults(items);
494
- setActive(0);
495
- } finally {
496
- setLoading(false);
497
- }
498
- }, [searchTerm]);
499
-
500
- useKeypress((key, rl) => {
501
- if (isEscapeKey(key)) {
502
- setStatus("cancelled");
503
- done(null);
504
- } else if (isEnterKey(key) && results.length > 0) {
505
- setStatus("done");
506
- done(results[active]?.value ?? null);
507
- } else if (isUpKey(key) && results.length > 0) {
508
- rl.clearLine(0);
509
- setActive(active > 0 ? active - 1 : results.length - 1);
510
- } else if (isDownKey(key) && results.length > 0) {
511
- rl.clearLine(0);
512
- setActive(active < results.length - 1 ? active + 1 : 0);
513
- } else if (isBackspaceKey(key)) {
514
- setSearchTerm(rl.line);
515
- } else if (key.name !== "tab" && !key.ctrl && !(key as any).meta) {
516
- setSearchTerm(rl.line);
517
- }
518
- });
501
+ export const searchCancellable = createPrompt<
502
+ unknown | null,
503
+ SearchConfig<unknown>
504
+ >((config, done) => {
505
+ const [status, setStatus] = useState<"idle" | "done" | "cancelled">("idle");
506
+ const [searchTerm, setSearchTerm] = useState("");
507
+ const [results, setResults] = useState<{ name: string; value: unknown }[]>(
508
+ [],
509
+ );
510
+ const [active, setActive] = useState(0);
511
+ const [loading, setLoading] = useState(false);
512
+ // Store selected item when Enter is pressed to avoid stale closure issues
513
+ const [selectedName, setSelectedName] = useState<string>("");
514
+ const theme = makeTheme(selectTheme);
515
+ const prefix = usePrefix({
516
+ status: status === "cancelled" ? "done" : status,
517
+ theme,
518
+ });
519
519
 
520
- if (status === "cancelled") {
521
- return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
520
+ // Fetch results when search term changes
521
+ useMemo(async () => {
522
+ setLoading(true);
523
+ try {
524
+ const items = await config.source(searchTerm || undefined);
525
+ setResults(items);
526
+ // Don't reset active here - it's reset in keypress handler when user types
527
+ } finally {
528
+ setLoading(false);
522
529
  }
530
+ }, [searchTerm]);
523
531
 
524
- if (status === "done") {
532
+ useKeypress((key, rl) => {
533
+ if (isEscapeKey(key)) {
534
+ setStatus("cancelled");
535
+ done(null);
536
+ } else if (isEnterKey(key) && results.length > 0) {
525
537
  const selected = results[active];
526
- return `${prefix} ${config.message} ${colors.cyan(selected?.name ?? "")}`;
538
+ setSelectedName(selected?.name ?? "");
539
+ setStatus("done");
540
+ done(selected?.value ?? null);
541
+ } else if (isUpKey(key) && results.length > 0) {
542
+ setActive(active > 0 ? active - 1 : results.length - 1);
543
+ } else if (isDownKey(key) && results.length > 0) {
544
+ setActive(active < results.length - 1 ? active + 1 : 0);
545
+ } else if (isBackspaceKey(key)) {
546
+ // Reset active when user modifies search term
547
+ setActive(0);
548
+ setSearchTerm(rl.line);
549
+ } else if (
550
+ key.name !== "tab" &&
551
+ key.name !== "return" &&
552
+ key.name !== "enter" &&
553
+ key.name !== "up" &&
554
+ key.name !== "down" &&
555
+ key.name !== "left" &&
556
+ key.name !== "right" &&
557
+ key.name !== "escape" &&
558
+ key.name !== "backspace" &&
559
+ !key.ctrl &&
560
+ !(key as any).meta
561
+ ) {
562
+ // Reset active when user types new characters (not navigation/action keys)
563
+ setActive(0);
564
+ setSearchTerm(rl.line);
527
565
  }
566
+ });
567
+
568
+ if (status === "cancelled") {
569
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
570
+ }
528
571
 
529
- const helpTip = colors.dim("(Type to search, Esc to cancel)");
530
- const searchLine = `${prefix} ${config.message} ${helpTip} ${searchTerm}`;
572
+ if (status === "done") {
573
+ return `${prefix} ${config.message} ${colors.cyan(selectedName)}`;
574
+ }
531
575
 
532
- if (loading) {
533
- return `${searchLine}\n${colors.dim(" Searching...")}`;
534
- }
576
+ const helpTip = colors.dim("(Type to search, Esc to cancel)");
577
+ const searchLine = `${prefix} ${config.message} ${helpTip} ${searchTerm}`;
535
578
 
536
- if (results.length === 0) {
537
- return `${searchLine}\n${colors.dim(" No results")}`;
538
- }
579
+ if (loading) {
580
+ return `${searchLine}\n${colors.dim(" Searching...")}`;
581
+ }
539
582
 
540
- const resultLines = results
541
- .slice(0, 7)
542
- .map((item, i) => {
543
- const cursor = i === active ? figures.pointer : " ";
544
- const color = i === active ? colors.cyan : (x: string) => x;
545
- return color(`${cursor} ${item.name}`);
546
- })
547
- .join("\n");
583
+ if (results.length === 0) {
584
+ return `${searchLine}\n${colors.dim(" No results")}`;
585
+ }
548
586
 
549
- return `${searchLine}\n${resultLines}`;
550
- },
551
- );
587
+ const resultLines = results
588
+ .slice(0, 7)
589
+ .map((item, i) => {
590
+ const cursor = i === active ? figures.pointer : " ";
591
+ const color = i === active ? colors.cyan : (x: string) => x;
592
+ return color(`${cursor} ${item.name}`);
593
+ })
594
+ .join("\n");
595
+
596
+ return `${searchLine}\n${resultLines}`;
597
+ });
@@ -78,6 +78,26 @@ export const MultisigScriptModule = Type.Module({
78
78
  export const MultisigScript = MultisigScriptModule.Import("MultisigScript");
79
79
  export type TMultisigScript = TExact<typeof MultisigScript>;
80
80
 
81
+ /**
82
+ * Native script input schema: accepts either a CBOR hex string or a MultisigScript JSON structure.
83
+ * Use as an optional array parameter on actions that build transactions.
84
+ */
85
+ export const NativeScriptInputSchema = Type.Union([
86
+ Type.String({ description: "Native script CBOR hex" }),
87
+ MultisigScript,
88
+ ]);
89
+
90
+ /**
91
+ * Optional array of native scripts to attach to a transaction.
92
+ * Reusable schema fragment for action input definitions.
93
+ */
94
+ export const NativeScriptsParam = Type.Optional(
95
+ Type.Array(NativeScriptInputSchema, {
96
+ description:
97
+ "Native scripts to attach to the transaction witness set (CBOR hex or MultisigScript JSON)",
98
+ }),
99
+ );
100
+
81
101
  /**
82
102
  * Provider settings schema for blockchain data providers.
83
103
  */
@@ -6,8 +6,11 @@
6
6
  import {
7
7
  Kind,
8
8
  type TBigInt,
9
+ type TBoolean,
10
+ type TInteger,
9
11
  type TLiteral,
10
12
  type TNull,
13
+ type TNumber,
11
14
  type TObject,
12
15
  type TSchema,
13
16
  type TString,
@@ -31,6 +34,12 @@ export const isArray = (t: TSchema): t is TArray => t[Kind] === "Array";
31
34
 
32
35
  export const isBigInt = (t: TSchema): t is TBigInt => t[Kind] === "BigInt";
33
36
 
37
+ export const isBoolean = (t: TSchema): t is TBoolean => t[Kind] === "Boolean";
38
+
39
+ export const isInteger = (t: TSchema): t is TInteger => t[Kind] === "Integer";
40
+
41
+ export const isNumber = (t: TSchema): t is TNumber => t[Kind] === "Number";
42
+
34
43
  export const isLiteral = (t: TSchema): t is TLiteral => t[Kind] === "Literal";
35
44
 
36
45
  export const isObject = (t: TSchema): t is TObject => t[Kind] === "Object";