@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.
- package/README.md +178 -181
- package/dist/cjs/Sprinkle/__tests__/action-integration.test.js +590 -0
- package/dist/cjs/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js +193 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js +304 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js +1110 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +744 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +711 -0
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/native-script.test.js +390 -0
- package/dist/cjs/Sprinkle/__tests__/native-script.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js +334 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js +367 -0
- package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js +749 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js +164 -0
- package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js +61 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js +174 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/native-script.js +139 -0
- package/dist/cjs/Sprinkle/actions/builtin/native-script.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js +202 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js +87 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js +345 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js +218 -0
- package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js +212 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js +390 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/index.js +139 -0
- package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js +557 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/registry.js +92 -0
- package/dist/cjs/Sprinkle/actions/registry.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/runner.js +190 -0
- package/dist/cjs/Sprinkle/actions/runner.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js +96 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/types.js +68 -0
- package/dist/cjs/Sprinkle/actions/types.js.map +1 -0
- package/dist/cjs/Sprinkle/index.js +678 -5
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/prompts.js +12 -7
- package/dist/cjs/Sprinkle/prompts.js.map +1 -1
- package/dist/cjs/Sprinkle/schemas.js +17 -1
- package/dist/cjs/Sprinkle/schemas.js.map +1 -1
- package/dist/cjs/Sprinkle/type-guards.js +7 -1
- package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js +588 -0
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js +192 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js +302 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +1107 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +742 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +710 -0
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/native-script.test.js +388 -0
- package/dist/esm/Sprinkle/__tests__/native-script.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js +332 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/utility-actions.test.js +365 -0
- package/dist/esm/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js +747 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js +159 -0
- package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js +55 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js +37 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/native-script.js +133 -0
- package/dist/esm/Sprinkle/actions/builtin/native-script.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js +197 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js +81 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js +340 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/utility-actions.js +213 -0
- package/dist/esm/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js +207 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js +379 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/index.js +12 -0
- package/dist/esm/Sprinkle/actions/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js +547 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/registry.js +85 -0
- package/dist/esm/Sprinkle/actions/registry.js.map +1 -0
- package/dist/esm/Sprinkle/actions/runner.js +182 -0
- package/dist/esm/Sprinkle/actions/runner.js.map +1 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js +91 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/esm/Sprinkle/actions/types.js +61 -0
- package/dist/esm/Sprinkle/actions/types.js.map +1 -0
- package/dist/esm/Sprinkle/index.js +517 -7
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/prompts.js +12 -7
- package/dist/esm/Sprinkle/prompts.js.map +1 -1
- package/dist/esm/Sprinkle/schemas.js +16 -0
- package/dist/esm/Sprinkle/schemas.js.map +1 -1
- package/dist/esm/Sprinkle/type-guards.js +3 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -1
- package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts +50 -0
- package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts +39 -0
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts +30 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/native-script.d.ts +27 -0
- package/dist/types/Sprinkle/actions/builtin/native-script.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts +55 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts +32 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts +70 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts +48 -0
- package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts +50 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts +104 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/index.d.ts +13 -0
- package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +116 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/registry.d.ts +42 -0
- package/dist/types/Sprinkle/actions/registry.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/runner.d.ts +45 -0
- package/dist/types/Sprinkle/actions/runner.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts +53 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/types.d.ts +76 -0
- package/dist/types/Sprinkle/actions/types.d.ts.map +1 -0
- package/dist/types/Sprinkle/index.d.ts +84 -2
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
- package/dist/types/Sprinkle/schemas.d.ts +72 -0
- package/dist/types/Sprinkle/schemas.d.ts.map +1 -1
- package/dist/types/Sprinkle/type-guards.d.ts +4 -1
- package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +9 -2
- package/src/Sprinkle/__tests__/action-integration.test.ts +558 -0
- package/src/Sprinkle/__tests__/action-registry.test.ts +187 -0
- package/src/Sprinkle/__tests__/action-runner.test.ts +324 -0
- package/src/Sprinkle/__tests__/builtin-actions.test.ts +1022 -0
- package/src/Sprinkle/__tests__/cli-adapter.test.ts +736 -0
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +23 -1
- package/src/Sprinkle/__tests__/mcp-adapter.test.ts +720 -0
- package/src/Sprinkle/__tests__/native-script.test.ts +341 -0
- package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
- package/src/Sprinkle/__tests__/utility-actions.test.ts +348 -0
- package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
- package/src/Sprinkle/actions/builtin/addressbook-actions.ts +168 -0
- package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
- package/src/Sprinkle/actions/builtin/index.ts +125 -0
- package/src/Sprinkle/actions/builtin/native-script.ts +165 -0
- package/src/Sprinkle/actions/builtin/profile-actions.ts +229 -0
- package/src/Sprinkle/actions/builtin/settings-actions.ts +99 -0
- package/src/Sprinkle/actions/builtin/transaction-actions.ts +381 -0
- package/src/Sprinkle/actions/builtin/utility-actions.ts +285 -0
- package/src/Sprinkle/actions/builtin/wallet-actions.ts +233 -0
- package/src/Sprinkle/actions/cli-adapter.ts +446 -0
- package/src/Sprinkle/actions/index.ts +33 -0
- package/src/Sprinkle/actions/mcp-adapter.ts +638 -0
- package/src/Sprinkle/actions/registry.ts +97 -0
- package/src/Sprinkle/actions/runner.ts +200 -0
- package/src/Sprinkle/actions/tui-helpers.ts +114 -0
- package/src/Sprinkle/actions/types.ts +91 -0
- package/src/Sprinkle/index.ts +612 -3
- package/src/Sprinkle/prompts.ts +118 -72
- package/src/Sprinkle/schemas.ts +20 -0
- package/src/Sprinkle/type-guards.ts +9 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in utility actions for the Sprinkle action system.
|
|
3
|
+
* These actions provide common Cardano operations: minting tokens,
|
|
4
|
+
* sending ADA/tokens, and registering stake scripts.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Type } from "@sinclair/typebox";
|
|
8
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
9
|
+
import { Core, makeValue } from "@blaze-cardano/sdk";
|
|
10
|
+
import { ActionError } from "../types.js";
|
|
11
|
+
import type { IAction } from "../types.js";
|
|
12
|
+
import { getBlazeFromContext, isHotWallet } from "./blaze-helper.js";
|
|
13
|
+
import { NativeScriptsParam } from "../../schemas.js";
|
|
14
|
+
import type { NativeScriptInput } from "./native-script.js";
|
|
15
|
+
import { completeWithScripts } from "./native-script.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* `mint-token` -- Mint native tokens using a native script derived from the wallet's payment key.
|
|
19
|
+
* The policy is a simple ScriptPubkey requiring the wallet's payment credential to sign.
|
|
20
|
+
* Requires a hot wallet.
|
|
21
|
+
*/
|
|
22
|
+
export const mintToken: IAction<
|
|
23
|
+
{ tokenName: string; amount: string; nativeScripts?: NativeScriptInput[] },
|
|
24
|
+
{ policyId: string; tokenName: string; amount: string; txCbor: string },
|
|
25
|
+
TSchema
|
|
26
|
+
> = {
|
|
27
|
+
name: "mint-token",
|
|
28
|
+
description:
|
|
29
|
+
"Mint native tokens using a native script policy derived from the wallet's payment key.",
|
|
30
|
+
category: "utility",
|
|
31
|
+
inputSchema: Type.Object({
|
|
32
|
+
tokenName: Type.String({ description: "Name of the token to mint" }),
|
|
33
|
+
amount: Type.String({
|
|
34
|
+
description: "Amount of tokens to mint (as string for BigInt safety)",
|
|
35
|
+
}),
|
|
36
|
+
nativeScripts: NativeScriptsParam,
|
|
37
|
+
}),
|
|
38
|
+
outputSchema: Type.Object({
|
|
39
|
+
policyId: Type.String({ description: "Policy ID of the minted token" }),
|
|
40
|
+
tokenName: Type.String({ description: "Token name" }),
|
|
41
|
+
amount: Type.String({ description: "Amount minted" }),
|
|
42
|
+
txCbor: Type.String({
|
|
43
|
+
description: "Unsigned transaction CBOR hex ready for signing",
|
|
44
|
+
}),
|
|
45
|
+
}),
|
|
46
|
+
execute: async (input, context) => {
|
|
47
|
+
const blaze = await getBlazeFromContext(context);
|
|
48
|
+
|
|
49
|
+
if (!isHotWallet(blaze)) {
|
|
50
|
+
throw new ActionError(
|
|
51
|
+
"Mint token requires a hot wallet to derive the native script policy.",
|
|
52
|
+
"COLD_WALLET",
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Get the wallet's payment credential hash for the native script
|
|
57
|
+
let address: Core.Address;
|
|
58
|
+
try {
|
|
59
|
+
address = await blaze.wallet.getChangeAddress();
|
|
60
|
+
} catch (err) {
|
|
61
|
+
throw new ActionError(
|
|
62
|
+
`Failed to get wallet address: ${err instanceof Error ? err.message : String(err)}`,
|
|
63
|
+
"NO_ADDRESS",
|
|
64
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const baseAddress = address.asBase();
|
|
69
|
+
if (!baseAddress) {
|
|
70
|
+
throw new ActionError(
|
|
71
|
+
"Could not derive base address from wallet. Ensure the wallet has a payment credential.",
|
|
72
|
+
"INVALID_ADDRESS",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const paymentCredential = baseAddress.getPaymentCredential();
|
|
77
|
+
if (!paymentCredential?.hash) {
|
|
78
|
+
throw new ActionError(
|
|
79
|
+
"Could not extract payment credential hash from wallet address.",
|
|
80
|
+
"NO_PAYMENT_CREDENTIAL",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const hash = Core.Ed25519KeyHashHex(paymentCredential.hash.toString());
|
|
85
|
+
const tokenPolicy = new Core.ScriptPubkey(hash);
|
|
86
|
+
const policy = Core.Script.newNativeScript(
|
|
87
|
+
Core.NativeScript.newScriptPubkey(tokenPolicy),
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const policyId = policy.hash();
|
|
91
|
+
const assetName = Core.AssetName(
|
|
92
|
+
Core.toHex(Buffer.from(input.tokenName)),
|
|
93
|
+
);
|
|
94
|
+
const mintAmount = BigInt(input.amount);
|
|
95
|
+
|
|
96
|
+
const mints = new Map<Core.AssetName, bigint>();
|
|
97
|
+
mints.set(assetName, mintAmount);
|
|
98
|
+
|
|
99
|
+
let tx: Core.Transaction;
|
|
100
|
+
try {
|
|
101
|
+
const txBuilder = blaze
|
|
102
|
+
.newTransaction()
|
|
103
|
+
.addMint(Core.PolicyId(policyId), mints)
|
|
104
|
+
.provideScript(policy);
|
|
105
|
+
tx = await completeWithScripts(txBuilder, input.nativeScripts, context);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err instanceof ActionError) throw err;
|
|
108
|
+
throw new ActionError(
|
|
109
|
+
`Failed to build mint transaction: ${err instanceof Error ? err.message : String(err)}`,
|
|
110
|
+
"BUILD_ERROR",
|
|
111
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
policyId: policyId.toString(),
|
|
117
|
+
tokenName: input.tokenName,
|
|
118
|
+
amount: input.amount,
|
|
119
|
+
txCbor: tx.toCbor(),
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* `simple-send` -- Send ADA or a native token to a recipient address.
|
|
126
|
+
* Builds an unsigned transaction that can be signed via TxDialog or sign-transaction.
|
|
127
|
+
*/
|
|
128
|
+
export const simpleSend: IAction<
|
|
129
|
+
{
|
|
130
|
+
recipientAddress: string;
|
|
131
|
+
lovelace?: string;
|
|
132
|
+
policyId?: string;
|
|
133
|
+
assetName?: string;
|
|
134
|
+
tokenAmount?: string;
|
|
135
|
+
nativeScripts?: NativeScriptInput[];
|
|
136
|
+
},
|
|
137
|
+
{ txCbor: string },
|
|
138
|
+
TSchema
|
|
139
|
+
> = {
|
|
140
|
+
name: "simple-send",
|
|
141
|
+
description: "Send ADA or a native token to a recipient address.",
|
|
142
|
+
category: "wallet",
|
|
143
|
+
inputSchema: Type.Object({
|
|
144
|
+
recipientAddress: Type.String({
|
|
145
|
+
description: "Bech32 recipient address",
|
|
146
|
+
}),
|
|
147
|
+
lovelace: Type.Optional(
|
|
148
|
+
Type.String({
|
|
149
|
+
description:
|
|
150
|
+
"Amount of lovelace to send (as string for BigInt safety). Required if not sending a token.",
|
|
151
|
+
}),
|
|
152
|
+
),
|
|
153
|
+
policyId: Type.Optional(
|
|
154
|
+
Type.String({ description: "Policy ID of the token to send" }),
|
|
155
|
+
),
|
|
156
|
+
assetName: Type.Optional(
|
|
157
|
+
Type.String({
|
|
158
|
+
description: "Asset name of the token to send (hex-encoded)",
|
|
159
|
+
}),
|
|
160
|
+
),
|
|
161
|
+
tokenAmount: Type.Optional(
|
|
162
|
+
Type.String({
|
|
163
|
+
description: "Amount of tokens to send (as string for BigInt safety)",
|
|
164
|
+
}),
|
|
165
|
+
),
|
|
166
|
+
nativeScripts: NativeScriptsParam,
|
|
167
|
+
}),
|
|
168
|
+
outputSchema: Type.Object({
|
|
169
|
+
txCbor: Type.String({
|
|
170
|
+
description: "Unsigned transaction CBOR hex ready for signing",
|
|
171
|
+
}),
|
|
172
|
+
}),
|
|
173
|
+
execute: async (input, context) => {
|
|
174
|
+
const blaze = await getBlazeFromContext(context);
|
|
175
|
+
|
|
176
|
+
// Validate: must provide lovelace or token details
|
|
177
|
+
const hasToken = input.policyId && input.assetName && input.tokenAmount;
|
|
178
|
+
if (!input.lovelace && !hasToken) {
|
|
179
|
+
throw new ActionError(
|
|
180
|
+
"Must provide either lovelace amount or token details (policyId, assetName, tokenAmount).",
|
|
181
|
+
"INVALID_INPUT",
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let recipient: Core.Address;
|
|
186
|
+
try {
|
|
187
|
+
recipient = Core.Address.fromBech32(input.recipientAddress);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
throw new ActionError(
|
|
190
|
+
`Invalid recipient address: ${err instanceof Error ? err.message : String(err)}`,
|
|
191
|
+
"INVALID_ADDRESS",
|
|
192
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let value: Core.Value;
|
|
197
|
+
if (hasToken) {
|
|
198
|
+
const assetId =
|
|
199
|
+
`${input.policyId}${input.assetName}` as Core.AssetId;
|
|
200
|
+
value = makeValue(
|
|
201
|
+
BigInt(input.lovelace ?? "0"),
|
|
202
|
+
[assetId, BigInt(input.tokenAmount!)],
|
|
203
|
+
);
|
|
204
|
+
} else {
|
|
205
|
+
value = makeValue(BigInt(input.lovelace!));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let tx: Core.Transaction;
|
|
209
|
+
try {
|
|
210
|
+
const txBuilder = blaze.newTransaction().payAssets(recipient, value);
|
|
211
|
+
tx = await completeWithScripts(txBuilder, input.nativeScripts, context);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
if (err instanceof ActionError) throw err;
|
|
214
|
+
throw new ActionError(
|
|
215
|
+
`Failed to build send transaction: ${err instanceof Error ? err.message : String(err)}`,
|
|
216
|
+
"BUILD_ERROR",
|
|
217
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
txCbor: tx.toCbor(),
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* `register-stake-script` -- Register a stake script credential on-chain.
|
|
229
|
+
* Takes a script hash and builds a stake registration transaction.
|
|
230
|
+
*/
|
|
231
|
+
export const registerStakeScript: IAction<
|
|
232
|
+
{ scriptHash: string; nativeScripts?: NativeScriptInput[] },
|
|
233
|
+
{ txCbor: string },
|
|
234
|
+
TSchema
|
|
235
|
+
> = {
|
|
236
|
+
name: "register-stake-script",
|
|
237
|
+
description:
|
|
238
|
+
"Register a stake script credential on-chain. Takes a script hash (hex) and builds the registration transaction.",
|
|
239
|
+
category: "utility",
|
|
240
|
+
inputSchema: Type.Object({
|
|
241
|
+
scriptHash: Type.String({
|
|
242
|
+
description: "Stake script hash in hex (28 bytes / 56 hex characters)",
|
|
243
|
+
}),
|
|
244
|
+
nativeScripts: NativeScriptsParam,
|
|
245
|
+
}),
|
|
246
|
+
outputSchema: Type.Object({
|
|
247
|
+
txCbor: Type.String({
|
|
248
|
+
description: "Unsigned transaction CBOR hex ready for signing",
|
|
249
|
+
}),
|
|
250
|
+
}),
|
|
251
|
+
execute: async (input, context) => {
|
|
252
|
+
const blaze = await getBlazeFromContext(context);
|
|
253
|
+
|
|
254
|
+
// Validate hex format
|
|
255
|
+
if (!/^[0-9a-fA-F]{56}$/.test(input.scriptHash)) {
|
|
256
|
+
throw new ActionError(
|
|
257
|
+
"Script hash must be exactly 56 hex characters (28 bytes).",
|
|
258
|
+
"INVALID_SCRIPT_HASH",
|
|
259
|
+
{ provided: input.scriptHash },
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const credential = Core.Credential.fromCore({
|
|
264
|
+
hash: Core.Hash28ByteBase16(input.scriptHash),
|
|
265
|
+
type: Core.CredentialType.ScriptHash,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
let tx: Core.Transaction;
|
|
269
|
+
try {
|
|
270
|
+
const txBuilder = blaze.newTransaction().addRegisterStake(credential);
|
|
271
|
+
tx = await completeWithScripts(txBuilder, input.nativeScripts, context);
|
|
272
|
+
} catch (err) {
|
|
273
|
+
if (err instanceof ActionError) throw err;
|
|
274
|
+
throw new ActionError(
|
|
275
|
+
`Failed to build stake registration transaction: ${err instanceof Error ? err.message : String(err)}`,
|
|
276
|
+
"BUILD_ERROR",
|
|
277
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
txCbor: tx.toCbor(),
|
|
283
|
+
};
|
|
284
|
+
},
|
|
285
|
+
};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in wallet query actions for the Sprinkle action system.
|
|
3
|
+
* These actions expose wallet address, balance, and UTxO queries as
|
|
4
|
+
* non-interactive actions available in CLI and MCP modes.
|
|
5
|
+
*
|
|
6
|
+
* All actions use category "wallet".
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Type } from "@sinclair/typebox";
|
|
10
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
11
|
+
import { Core } from "@blaze-cardano/sdk";
|
|
12
|
+
import { ActionError } from "../types.js";
|
|
13
|
+
import type { IAction } from "../types.js";
|
|
14
|
+
import { getBlazeFromContext } from "./blaze-helper.js";
|
|
15
|
+
|
|
16
|
+
/** Shared token entry shape for balance and UTxO output */
|
|
17
|
+
const TokenEntrySchema = Type.Object({
|
|
18
|
+
policyId: Type.String({ description: "Policy ID of the token" }),
|
|
19
|
+
assetName: Type.String({ description: "Asset name of the token (hex)" }),
|
|
20
|
+
quantity: Type.String({ description: "Token quantity as string (BigInt-safe)" }),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* `get-wallet-address` -- Returns the primary change address of the configured wallet.
|
|
25
|
+
*/
|
|
26
|
+
export const getWalletAddress: IAction<
|
|
27
|
+
Record<string, never>,
|
|
28
|
+
{ address: string; network: string },
|
|
29
|
+
TSchema
|
|
30
|
+
> = {
|
|
31
|
+
name: "get-wallet-address",
|
|
32
|
+
description: "Get the primary address of the configured wallet.",
|
|
33
|
+
category: "wallet",
|
|
34
|
+
inputSchema: Type.Object({}),
|
|
35
|
+
outputSchema: Type.Object({
|
|
36
|
+
address: Type.String({ description: "Bech32-encoded payment/change address" }),
|
|
37
|
+
network: Type.String({ description: "Network name (mainnet, preview, preprod)" }),
|
|
38
|
+
}),
|
|
39
|
+
execute: async (_input, context) => {
|
|
40
|
+
const blaze = await getBlazeFromContext(context);
|
|
41
|
+
|
|
42
|
+
let address: Core.Address;
|
|
43
|
+
try {
|
|
44
|
+
address = await blaze.wallet.getChangeAddress();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
throw new ActionError(
|
|
47
|
+
`Failed to get wallet address: ${err instanceof Error ? err.message : String(err)}`,
|
|
48
|
+
"NO_ADDRESS",
|
|
49
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!address) {
|
|
54
|
+
throw new ActionError(
|
|
55
|
+
"The wallet returned no address. Ensure the wallet is properly configured.",
|
|
56
|
+
"NO_ADDRESS",
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const settings = context.settings as unknown as { network?: string };
|
|
61
|
+
const network = settings.network ?? "unknown";
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
address: address.toBech32(),
|
|
65
|
+
network,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* `get-wallet-balance` -- Returns the ADA and token balance of the configured wallet.
|
|
72
|
+
* Aggregates lovelace and multi-asset amounts from all UTxOs.
|
|
73
|
+
* All quantities are returned as strings for BigInt-safe JSON serialization.
|
|
74
|
+
*/
|
|
75
|
+
export const getWalletBalance: IAction<
|
|
76
|
+
Record<string, never>,
|
|
77
|
+
{
|
|
78
|
+
lovelace: string;
|
|
79
|
+
ada: string;
|
|
80
|
+
tokens: Array<{ policyId: string; assetName: string; quantity: string }>;
|
|
81
|
+
},
|
|
82
|
+
TSchema
|
|
83
|
+
> = {
|
|
84
|
+
name: "get-wallet-balance",
|
|
85
|
+
description:
|
|
86
|
+
"Get the ADA and token balance of the configured wallet. Quantities returned as strings.",
|
|
87
|
+
category: "wallet",
|
|
88
|
+
inputSchema: Type.Object({}),
|
|
89
|
+
outputSchema: Type.Object({
|
|
90
|
+
lovelace: Type.String({
|
|
91
|
+
description: "Total ADA balance in lovelace (as string for BigInt safety)",
|
|
92
|
+
}),
|
|
93
|
+
ada: Type.String({ description: "Total ADA balance as decimal string" }),
|
|
94
|
+
tokens: Type.Array(TokenEntrySchema),
|
|
95
|
+
}),
|
|
96
|
+
execute: async (_input, context) => {
|
|
97
|
+
const blaze = await getBlazeFromContext(context);
|
|
98
|
+
|
|
99
|
+
let utxos: Awaited<ReturnType<typeof blaze.wallet.getUnspentOutputs>>;
|
|
100
|
+
try {
|
|
101
|
+
utxos = await blaze.wallet.getUnspentOutputs();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
throw new ActionError(
|
|
104
|
+
`Provider error while fetching UTxOs: ${err instanceof Error ? err.message : String(err)}`,
|
|
105
|
+
"PROVIDER_ERROR",
|
|
106
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Aggregate lovelace and token amounts
|
|
111
|
+
let totalLovelace = 0n;
|
|
112
|
+
const tokenMap = new Map<string, bigint>(); // key: `${policyId}.${assetName}`
|
|
113
|
+
|
|
114
|
+
for (const utxo of utxos) {
|
|
115
|
+
const value = utxo.output().amount();
|
|
116
|
+
totalLovelace += value.coin();
|
|
117
|
+
|
|
118
|
+
const multiasset = value.multiasset();
|
|
119
|
+
if (multiasset) {
|
|
120
|
+
for (const [assetId, quantity] of multiasset.entries()) {
|
|
121
|
+
const policyId = Core.AssetId.getPolicyId(assetId);
|
|
122
|
+
const assetName = Core.AssetId.getAssetName(assetId);
|
|
123
|
+
const key = `${policyId}.${assetName}`;
|
|
124
|
+
tokenMap.set(key, (tokenMap.get(key) ?? 0n) + quantity);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Convert tokens map to array, serializing BigInt quantities as strings
|
|
130
|
+
const tokens = Array.from(tokenMap.entries()).map(([key, quantity]) => {
|
|
131
|
+
const [policyId, assetName] = key.split(".");
|
|
132
|
+
return {
|
|
133
|
+
policyId: policyId ?? "",
|
|
134
|
+
assetName: assetName ?? "",
|
|
135
|
+
quantity: quantity.toString(),
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// ADA = lovelace / 1_000_000, with 6 decimal places
|
|
140
|
+
const adaWhole = totalLovelace / 1_000_000n;
|
|
141
|
+
const adaFraction = totalLovelace % 1_000_000n;
|
|
142
|
+
const ada = `${adaWhole}.${adaFraction.toString().padStart(6, "0")}`;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
lovelace: totalLovelace.toString(),
|
|
146
|
+
ada,
|
|
147
|
+
tokens,
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* `get-wallet-utxos` -- Returns raw UTxO set for the configured wallet.
|
|
154
|
+
* Accepts an optional limit (default 100). Returns UTxOs and the total count.
|
|
155
|
+
*/
|
|
156
|
+
export const getWalletUtxos: IAction<
|
|
157
|
+
{ limit?: number },
|
|
158
|
+
{
|
|
159
|
+
utxos: Array<{
|
|
160
|
+
txHash: string;
|
|
161
|
+
outputIndex: number;
|
|
162
|
+
lovelace: string;
|
|
163
|
+
tokens: Array<{ policyId: string; assetName: string; quantity: string }>;
|
|
164
|
+
}>;
|
|
165
|
+
total: number;
|
|
166
|
+
},
|
|
167
|
+
TSchema
|
|
168
|
+
> = {
|
|
169
|
+
name: "get-wallet-utxos",
|
|
170
|
+
description: "Get the UTxO set for the configured wallet.",
|
|
171
|
+
category: "wallet",
|
|
172
|
+
inputSchema: Type.Object({
|
|
173
|
+
limit: Type.Optional(
|
|
174
|
+
Type.Number({ default: 100, description: "Maximum number of UTxOs to return" }),
|
|
175
|
+
),
|
|
176
|
+
}),
|
|
177
|
+
outputSchema: Type.Object({
|
|
178
|
+
utxos: Type.Array(
|
|
179
|
+
Type.Object({
|
|
180
|
+
txHash: Type.String({ description: "Transaction hash of the UTxO" }),
|
|
181
|
+
outputIndex: Type.Number({ description: "Output index within the transaction" }),
|
|
182
|
+
lovelace: Type.String({ description: "Lovelace amount as string (BigInt-safe)" }),
|
|
183
|
+
tokens: Type.Array(TokenEntrySchema),
|
|
184
|
+
}),
|
|
185
|
+
),
|
|
186
|
+
total: Type.Number({ description: "Total number of UTxOs (before limit)" }),
|
|
187
|
+
}),
|
|
188
|
+
execute: async (input, context) => {
|
|
189
|
+
const blaze = await getBlazeFromContext(context);
|
|
190
|
+
const limit = input.limit ?? 100;
|
|
191
|
+
|
|
192
|
+
let allUtxos: Awaited<ReturnType<typeof blaze.wallet.getUnspentOutputs>>;
|
|
193
|
+
try {
|
|
194
|
+
allUtxos = await blaze.wallet.getUnspentOutputs();
|
|
195
|
+
} catch (err) {
|
|
196
|
+
throw new ActionError(
|
|
197
|
+
`Provider error while fetching UTxOs: ${err instanceof Error ? err.message : String(err)}`,
|
|
198
|
+
"PROVIDER_ERROR",
|
|
199
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const total = allUtxos.length;
|
|
204
|
+
const limited = allUtxos.slice(0, limit);
|
|
205
|
+
|
|
206
|
+
const utxos = limited.map((utxo) => {
|
|
207
|
+
const input = utxo.input();
|
|
208
|
+
const output = utxo.output();
|
|
209
|
+
const value = output.amount();
|
|
210
|
+
|
|
211
|
+
const tokens: Array<{ policyId: string; assetName: string; quantity: string }> = [];
|
|
212
|
+
const multiasset = value.multiasset();
|
|
213
|
+
if (multiasset) {
|
|
214
|
+
for (const [assetId, quantity] of multiasset.entries()) {
|
|
215
|
+
tokens.push({
|
|
216
|
+
policyId: Core.AssetId.getPolicyId(assetId),
|
|
217
|
+
assetName: Core.AssetId.getAssetName(assetId),
|
|
218
|
+
quantity: quantity.toString(),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
txHash: input.transactionId().toString(),
|
|
225
|
+
outputIndex: Number(input.index()),
|
|
226
|
+
lovelace: value.coin().toString(),
|
|
227
|
+
tokens,
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
return { utxos, total };
|
|
232
|
+
},
|
|
233
|
+
};
|