@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
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Built-in addressbook actions for managing named native scripts.
3
+ *
4
+ * The addressbook stores MultisigScript entries by name in the profile,
5
+ * allowing them to be reused across actions and automatically resolved
6
+ * by script hash during transaction building.
7
+ */
8
+
9
+ import { Type } from "@sinclair/typebox";
10
+ import type { TSchema } from "@sinclair/typebox";
11
+ import { MultisigScript } from "../../schemas.js";
12
+ import type { TMultisigScript } from "../../schemas.js";
13
+ import { ActionError } from "../types.js";
14
+ import type { IAction } from "../types.js";
15
+ import { toNativeScript } from "./native-script.js";
16
+
17
+ /**
18
+ * `list-addressbook` -- List all entries in the addressbook.
19
+ */
20
+ export const listAddressbook: IAction<
21
+ Record<string, never>,
22
+ { entries: Array<{ name: string; scriptHash: string; script: TMultisigScript }> },
23
+ TSchema
24
+ > = {
25
+ name: "list-addressbook",
26
+ description: "List all named native scripts in the addressbook.",
27
+ category: "addressbook",
28
+ inputSchema: Type.Object({}),
29
+ outputSchema: Type.Object({
30
+ entries: Type.Array(
31
+ Type.Object({
32
+ name: Type.String(),
33
+ scriptHash: Type.String(),
34
+ script: MultisigScript,
35
+ }),
36
+ ),
37
+ }),
38
+ execute: async (_input, context) => {
39
+ const addressbook = context.sprinkle.addressbook ?? {};
40
+ const entries = [];
41
+ for (const [name, ms] of Object.entries(addressbook)) {
42
+ try {
43
+ const script = toNativeScript(ms);
44
+ entries.push({ name, scriptHash: script.hash(), script: ms });
45
+ } catch {
46
+ // Include entries even if hash computation fails
47
+ entries.push({ name, scriptHash: "unknown", script: ms });
48
+ }
49
+ }
50
+ return { entries };
51
+ },
52
+ };
53
+
54
+ /**
55
+ * `set-addressbook-entry` -- Add or update a named native script in the addressbook.
56
+ */
57
+ export const setAddressbookEntry: IAction<
58
+ { name: string; script: TMultisigScript },
59
+ { name: string; scriptHash: string },
60
+ TSchema
61
+ > = {
62
+ name: "set-addressbook-entry",
63
+ description:
64
+ "Add or update a named native script in the addressbook. Accepts a MultisigScript JSON structure.",
65
+ category: "addressbook",
66
+ inputSchema: Type.Object({
67
+ name: Type.String({
68
+ minLength: 1,
69
+ description: "Name for this addressbook entry",
70
+ }),
71
+ script: MultisigScript,
72
+ }),
73
+ outputSchema: Type.Object({
74
+ name: Type.String(),
75
+ scriptHash: Type.String({ description: "Computed script hash" }),
76
+ }),
77
+ execute: async (input, context) => {
78
+ // Validate the script can be converted
79
+ const blazeScript = toNativeScript(input.script);
80
+ const scriptHash = blazeScript.hash();
81
+
82
+ context.sprinkle.addressbook[input.name] = input.script;
83
+ context.sprinkle.saveSettings();
84
+
85
+ return { name: input.name, scriptHash };
86
+ },
87
+ };
88
+
89
+ /**
90
+ * `delete-addressbook-entry` -- Remove a named native script from the addressbook.
91
+ */
92
+ export const deleteAddressbookEntry: IAction<
93
+ { name: string },
94
+ { deleted: boolean; name: string },
95
+ TSchema
96
+ > = {
97
+ name: "delete-addressbook-entry",
98
+ description: "Remove a named native script from the addressbook.",
99
+ category: "addressbook",
100
+ inputSchema: Type.Object({
101
+ name: Type.String({
102
+ minLength: 1,
103
+ description: "Name of the addressbook entry to delete",
104
+ }),
105
+ }),
106
+ outputSchema: Type.Object({
107
+ deleted: Type.Boolean(),
108
+ name: Type.String(),
109
+ }),
110
+ execute: async (input, context) => {
111
+ if (!(input.name in context.sprinkle.addressbook)) {
112
+ throw new ActionError(
113
+ `Addressbook entry "${input.name}" not found.`,
114
+ "NOT_FOUND",
115
+ { name: input.name },
116
+ );
117
+ }
118
+
119
+ delete context.sprinkle.addressbook[input.name];
120
+ context.sprinkle.saveSettings();
121
+
122
+ return { deleted: true, name: input.name };
123
+ },
124
+ };
125
+
126
+ /**
127
+ * `get-addressbook-entry` -- Get a specific named native script from the addressbook.
128
+ */
129
+ export const getAddressbookEntry: IAction<
130
+ { name: string },
131
+ { name: string; scriptHash: string; script: TMultisigScript },
132
+ TSchema
133
+ > = {
134
+ name: "get-addressbook-entry",
135
+ description: "Get a specific named native script from the addressbook.",
136
+ category: "addressbook",
137
+ inputSchema: Type.Object({
138
+ name: Type.String({
139
+ minLength: 1,
140
+ description: "Name of the addressbook entry to retrieve",
141
+ }),
142
+ }),
143
+ outputSchema: Type.Object({
144
+ name: Type.String(),
145
+ scriptHash: Type.String(),
146
+ script: MultisigScript,
147
+ }),
148
+ execute: async (input, context) => {
149
+ const ms = context.sprinkle.addressbook[input.name];
150
+ if (!ms) {
151
+ throw new ActionError(
152
+ `Addressbook entry "${input.name}" not found.`,
153
+ "NOT_FOUND",
154
+ { name: input.name },
155
+ );
156
+ }
157
+
158
+ let scriptHash = "unknown";
159
+ try {
160
+ const blazeScript = toNativeScript(ms);
161
+ scriptHash = blazeScript.hash();
162
+ } catch {
163
+ // Return entry even if hash computation fails
164
+ }
165
+
166
+ return { name: input.name, scriptHash, script: ms };
167
+ },
168
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Shared helper utilities for wallet and transaction actions.
3
+ * Provides Blaze instance creation from action context settings.
4
+ */
5
+
6
+ import type { TSchema } from "@sinclair/typebox";
7
+ import { Blaze, HotWallet } from "@blaze-cardano/sdk";
8
+ import type { Provider } from "@blaze-cardano/query";
9
+ import type { Wallet } from "@blaze-cardano/sdk";
10
+ import { GetBlaze } from "../../wallet.js";
11
+ import { ActionError } from "../types.js";
12
+ import type { IActionContext } from "../types.js";
13
+ import type {
14
+ NetworkSchema,
15
+ ProviderSettingsSchema,
16
+ WalletSettingsSchema,
17
+ } from "../../schemas.js";
18
+ import type { TExact } from "../../types.js";
19
+
20
+ /** Settings shape expected on context.settings for wallet access */
21
+ export interface IWalletSettings {
22
+ network?: TExact<typeof NetworkSchema>;
23
+ provider?: TExact<typeof ProviderSettingsSchema>;
24
+ wallet?: TExact<typeof WalletSettingsSchema>;
25
+ }
26
+
27
+ /** Optional overrides for Blaze initialization, in case field names differ */
28
+ export interface IBlazeOverrides {
29
+ network?: TExact<typeof NetworkSchema>;
30
+ provider?: TExact<typeof ProviderSettingsSchema>;
31
+ wallet?: TExact<typeof WalletSettingsSchema>;
32
+ }
33
+
34
+ /**
35
+ * Creates a Blaze instance from action context settings.
36
+ *
37
+ * Falls back to `context.settings.network`, `context.settings.provider`,
38
+ * and `context.settings.wallet` when overrides are not provided.
39
+ *
40
+ * @throws `ActionError("WALLET_NOT_CONFIGURED")` if required settings are missing
41
+ * @throws `ActionError("BLAZE_INIT_ERROR")` if Blaze fails to initialize
42
+ */
43
+ export async function getBlazeFromContext<S extends TSchema>(
44
+ context: IActionContext<S>,
45
+ overrides?: IBlazeOverrides,
46
+ ): Promise<Blaze<Provider, Wallet>> {
47
+ const settings = context.settings as unknown as IWalletSettings;
48
+
49
+ const network = overrides?.network ?? settings.network;
50
+ const provider = overrides?.provider ?? settings.provider;
51
+ const wallet = overrides?.wallet ?? settings.wallet;
52
+
53
+ // Validate required fields and collect missing ones for a helpful error message
54
+ const missing: string[] = [];
55
+ if (!network) missing.push("network");
56
+ if (!provider) missing.push("provider");
57
+ if (!wallet) missing.push("wallet");
58
+
59
+ if (missing.length > 0) {
60
+ throw new ActionError(
61
+ `Wallet is not configured. Missing settings: ${missing.join(", ")}. ` +
62
+ `Set these fields in your profile settings before using wallet actions.`,
63
+ "WALLET_NOT_CONFIGURED",
64
+ { missingFields: missing },
65
+ );
66
+ }
67
+
68
+ try {
69
+ return await GetBlaze(
70
+ network as TExact<typeof NetworkSchema>,
71
+ provider as TExact<typeof ProviderSettingsSchema>,
72
+ wallet as TExact<typeof WalletSettingsSchema>,
73
+ );
74
+ } catch (err) {
75
+ throw new ActionError(
76
+ `Failed to initialize Blaze wallet: ${err instanceof Error ? err.message : String(err)}`,
77
+ "BLAZE_INIT_ERROR",
78
+ { error: err instanceof Error ? err.message : String(err) },
79
+ );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Checks whether the wallet in a Blaze instance is a hot wallet.
85
+ * Cold wallets cannot sign transactions.
86
+ */
87
+ export function isHotWallet(blaze: Blaze<Provider, Wallet>): boolean {
88
+ return blaze.wallet instanceof HotWallet;
89
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Barrel export for built-in Sprinkle actions.
3
+ *
4
+ * Provides a `getBuiltinActions()` factory that returns all 17 built-in actions
5
+ * ready for registration on an ActionRegistry.
6
+ */
7
+
8
+ import type { TSchema } from "@sinclair/typebox";
9
+ import type { AnyAction } from "../types.js";
10
+
11
+ export {
12
+ listProfiles,
13
+ getProfile,
14
+ setProfile,
15
+ createProfile,
16
+ deleteProfile,
17
+ } from "./profile-actions.js";
18
+
19
+ export { getSettings, updateSettings } from "./settings-actions.js";
20
+
21
+ export {
22
+ getWalletAddress,
23
+ getWalletBalance,
24
+ getWalletUtxos,
25
+ } from "./wallet-actions.js";
26
+
27
+ export {
28
+ signTransaction,
29
+ submitTransaction,
30
+ signAndSubmit,
31
+ decodeTransaction,
32
+ } from "./transaction-actions.js";
33
+
34
+ export {
35
+ mintToken,
36
+ simpleSend,
37
+ registerStakeScript,
38
+ } from "./utility-actions.js";
39
+
40
+ export {
41
+ toNativeScript,
42
+ completeWithScripts,
43
+ } from "./native-script.js";
44
+ export type { NativeScriptInput } from "./native-script.js";
45
+
46
+ export {
47
+ listAddressbook,
48
+ getAddressbookEntry,
49
+ setAddressbookEntry,
50
+ deleteAddressbookEntry,
51
+ } from "./addressbook-actions.js";
52
+
53
+ import {
54
+ listProfiles,
55
+ getProfile,
56
+ setProfile,
57
+ createProfile,
58
+ deleteProfile,
59
+ } from "./profile-actions.js";
60
+
61
+ import { getSettings, updateSettings } from "./settings-actions.js";
62
+
63
+ import {
64
+ getWalletAddress,
65
+ getWalletBalance,
66
+ getWalletUtxos,
67
+ } from "./wallet-actions.js";
68
+
69
+ import {
70
+ signTransaction,
71
+ submitTransaction,
72
+ signAndSubmit,
73
+ decodeTransaction,
74
+ } from "./transaction-actions.js";
75
+
76
+ import {
77
+ mintToken,
78
+ simpleSend,
79
+ registerStakeScript,
80
+ } from "./utility-actions.js";
81
+
82
+ import {
83
+ listAddressbook,
84
+ getAddressbookEntry,
85
+ setAddressbookEntry,
86
+ deleteAddressbookEntry,
87
+ } from "./addressbook-actions.js";
88
+
89
+ /**
90
+ * Returns all built-in Sprinkle actions.
91
+ * Register them on your ActionRegistry or pass them to `Sprinkle.run()`.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * const sprinkle = new Sprinkle(MySchema, storagePath);
96
+ * for (const action of getBuiltinActions()) {
97
+ * sprinkle.registerAction(action);
98
+ * }
99
+ * ```
100
+ */
101
+ export function getBuiltinActions<S extends TSchema>(): AnyAction<S>[] {
102
+ return [
103
+ listProfiles,
104
+ getProfile,
105
+ setProfile,
106
+ createProfile,
107
+ deleteProfile,
108
+ getSettings,
109
+ updateSettings,
110
+ getWalletAddress,
111
+ getWalletBalance,
112
+ getWalletUtxos,
113
+ signTransaction,
114
+ submitTransaction,
115
+ signAndSubmit,
116
+ decodeTransaction,
117
+ mintToken,
118
+ simpleSend,
119
+ registerStakeScript,
120
+ listAddressbook,
121
+ getAddressbookEntry,
122
+ setAddressbookEntry,
123
+ deleteAddressbookEntry,
124
+ ] as unknown as AnyAction<S>[];
125
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Native script utilities for Sprinkle actions.
3
+ *
4
+ * Provides conversion from user-friendly input formats (CBOR hex or structured JSON)
5
+ * to Blaze NativeScript objects, and a helper to attach scripts during tx completion.
6
+ */
7
+
8
+ import { Core } from "@blaze-cardano/sdk";
9
+ import type { TxBuilder } from "@blaze-cardano/tx";
10
+ import type { TSchema } from "@sinclair/typebox";
11
+ import type { TMultisigScript } from "../../schemas.js";
12
+ import { ActionError } from "../types.js";
13
+ import type { IActionContext } from "../types.js";
14
+
15
+ /** Input type: either a CBOR hex string or a MultisigScript JSON structure */
16
+ export type NativeScriptInput = string | TMultisigScript;
17
+
18
+ /**
19
+ * Converts a MultisigScript JSON structure to a Blaze NativeScript.
20
+ * Handles the recursive structure (AllOf, AnyOf, AtLeast contain nested scripts).
21
+ */
22
+ function multisigToNativeScript(ms: TMultisigScript): Core.NativeScript {
23
+ if ("Signature" in ms) {
24
+ const hash = Core.Ed25519KeyHashHex(ms.Signature.key_hash);
25
+ return Core.NativeScript.newScriptPubkey(new Core.ScriptPubkey(hash));
26
+ }
27
+ if ("AllOf" in ms) {
28
+ const scripts = ms.AllOf.scripts.map(multisigToNativeScript);
29
+ return Core.NativeScript.newScriptAll(new Core.ScriptAll(scripts));
30
+ }
31
+ if ("AnyOf" in ms) {
32
+ const scripts = ms.AnyOf.scripts.map(multisigToNativeScript);
33
+ return Core.NativeScript.newScriptAny(new Core.ScriptAny(scripts));
34
+ }
35
+ if ("AtLeast" in ms) {
36
+ const scripts = ms.AtLeast.scripts.map(multisigToNativeScript);
37
+ return Core.NativeScript.newScriptNOfK(
38
+ new Core.ScriptNOfK(scripts, Number(ms.AtLeast.required)),
39
+ );
40
+ }
41
+ if ("Before" in ms) {
42
+ return Core.NativeScript.newTimelockExpiry(
43
+ new Core.TimelockExpiry(Core.Slot(Number(ms.Before.time))),
44
+ );
45
+ }
46
+ if ("After" in ms) {
47
+ return Core.NativeScript.newTimelockStart(
48
+ new Core.TimelockStart(Core.Slot(Number(ms.After.time))),
49
+ );
50
+ }
51
+ if ("Script" in ms) {
52
+ // Script variant references a script by hash — this is a ScriptPubkey
53
+ // but using the script hash directly as a key hash reference
54
+ const hash = Core.Ed25519KeyHashHex(ms.Script.script_hash);
55
+ return Core.NativeScript.newScriptPubkey(new Core.ScriptPubkey(hash));
56
+ }
57
+
58
+ throw new ActionError(
59
+ "Unrecognized MultisigScript variant",
60
+ "INVALID_NATIVE_SCRIPT",
61
+ { input: ms },
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Converts a native script input (CBOR hex string or MultisigScript JSON)
67
+ * to a Blaze Script object suitable for `provideScript()`.
68
+ */
69
+ export function toNativeScript(input: NativeScriptInput): Core.Script {
70
+ if (typeof input === "string") {
71
+ try {
72
+ const nativeScript = Core.NativeScript.fromCbor(
73
+ Core.HexBlob(input),
74
+ );
75
+ return Core.Script.newNativeScript(nativeScript);
76
+ } catch (err) {
77
+ throw new ActionError(
78
+ `Invalid native script CBOR: ${err instanceof Error ? err.message : String(err)}`,
79
+ "INVALID_NATIVE_SCRIPT",
80
+ { error: err instanceof Error ? err.message : String(err) },
81
+ );
82
+ }
83
+ }
84
+
85
+ try {
86
+ const nativeScript = multisigToNativeScript(input);
87
+ return Core.Script.newNativeScript(nativeScript);
88
+ } catch (err) {
89
+ if (err instanceof ActionError) throw err;
90
+ throw new ActionError(
91
+ `Failed to convert MultisigScript to native script: ${err instanceof Error ? err.message : String(err)}`,
92
+ "INVALID_NATIVE_SCRIPT",
93
+ { error: err instanceof Error ? err.message : String(err) },
94
+ );
95
+ }
96
+ }
97
+
98
+ /** Regex to extract a script hash from Blaze's "Could not resolve script hash" error */
99
+ const MISSING_SCRIPT_HASH_RE =
100
+ /complete: Could not resolve script hash[: ]*([0-9a-fA-F]+)/;
101
+
102
+ /**
103
+ * Builds a hash → Script lookup from the addressbook in the sprinkle context.
104
+ * Returns an empty map if there's no addressbook.
105
+ */
106
+ function buildAddressbookIndex(
107
+ addressbook: Record<string, TMultisigScript> | undefined,
108
+ ): Map<string, Core.Script> {
109
+ const index = new Map<string, Core.Script>();
110
+ if (!addressbook) return index;
111
+ for (const [, ms] of Object.entries(addressbook)) {
112
+ try {
113
+ const script = toNativeScript(ms);
114
+ index.set(script.hash(), script);
115
+ } catch {
116
+ // Skip invalid addressbook entries
117
+ }
118
+ }
119
+ return index;
120
+ }
121
+
122
+ /**
123
+ * Attaches optional native scripts to a transaction builder and completes it.
124
+ *
125
+ * If completion fails because Blaze cannot resolve a required native script hash,
126
+ * and a context with an addressbook is provided, it will look up the missing script
127
+ * by hash in the addressbook and retry once.
128
+ */
129
+ export async function completeWithScripts<S extends TSchema>(
130
+ txBuilder: TxBuilder,
131
+ nativeScripts?: NativeScriptInput[],
132
+ context?: IActionContext<S>,
133
+ ): Promise<Core.Transaction> {
134
+ if (nativeScripts?.length) {
135
+ for (const input of nativeScripts) {
136
+ txBuilder.provideScript(toNativeScript(input));
137
+ }
138
+ }
139
+
140
+ try {
141
+ return await txBuilder.complete();
142
+ } catch (err) {
143
+ const message = err instanceof Error ? err.message : String(err);
144
+ const match = message.match(MISSING_SCRIPT_HASH_RE);
145
+
146
+ if (!match || !context?.sprinkle?.addressbook) {
147
+ throw err;
148
+ }
149
+
150
+ // Build hash index from addressbook and try to resolve the missing script
151
+ const addressbookIndex = buildAddressbookIndex(
152
+ context.sprinkle.addressbook,
153
+ );
154
+ const missingHash = match[1];
155
+ const script = addressbookIndex.get(missingHash);
156
+
157
+ if (!script) {
158
+ throw err;
159
+ }
160
+
161
+ // Attach the found script and retry
162
+ txBuilder.provideScript(script);
163
+ return txBuilder.complete();
164
+ }
165
+ }