@sundaeswap/sprinkles 0.7.0 → 0.8.1
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__/builtin-actions.test.js +4 -4
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +25 -3
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -1
- 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 +7 -9
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -1
- 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__/utility-actions.test.js +367 -0
- package/dist/cjs/Sprinkle/__tests__/utility-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/index.js +60 -3
- package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -1
- 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/utility-actions.js +218 -0
- package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js +20 -2
- package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -1
- package/dist/cjs/Sprinkle/actions/index.js +12 -0
- package/dist/cjs/Sprinkle/actions/index.js.map +1 -1
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js +146 -4
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -1
- package/dist/cjs/Sprinkle/index.js +282 -6
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/schemas.js +17 -1
- package/dist/cjs/Sprinkle/schemas.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +4 -4
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +25 -3
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -1
- 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 +7 -9
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -1
- 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__/utility-actions.test.js +365 -0
- package/dist/esm/Sprinkle/__tests__/utility-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/index.js +8 -3
- package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -1
- 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/utility-actions.js +213 -0
- package/dist/esm/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js +20 -2
- package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -1
- package/dist/esm/Sprinkle/actions/index.js +1 -1
- package/dist/esm/Sprinkle/actions/index.js.map +1 -1
- package/dist/esm/Sprinkle/actions/mcp-adapter.js +145 -5
- package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -1
- package/dist/esm/Sprinkle/index.js +260 -9
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/schemas.js +16 -0
- package/dist/esm/Sprinkle/schemas.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/index.d.ts +6 -2
- package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -1
- 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/utility-actions.d.ts +48 -0
- package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -1
- package/dist/types/Sprinkle/actions/index.d.ts +2 -1
- package/dist/types/Sprinkle/actions/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +24 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -1
- package/dist/types/Sprinkle/index.d.ts +5 -2
- package/dist/types/Sprinkle/index.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/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Sprinkle/__tests__/builtin-actions.test.ts +4 -4
- package/src/Sprinkle/__tests__/cli-adapter.test.ts +24 -3
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +23 -1
- package/src/Sprinkle/__tests__/mcp-adapter.test.ts +7 -5
- package/src/Sprinkle/__tests__/native-script.test.ts +341 -0
- package/src/Sprinkle/__tests__/utility-actions.test.ts +348 -0
- package/src/Sprinkle/actions/builtin/addressbook-actions.ts +168 -0
- package/src/Sprinkle/actions/builtin/index.ts +41 -2
- package/src/Sprinkle/actions/builtin/native-script.ts +165 -0
- package/src/Sprinkle/actions/builtin/utility-actions.ts +285 -0
- package/src/Sprinkle/actions/cli-adapter.ts +18 -2
- package/src/Sprinkle/actions/index.ts +2 -1
- package/src/Sprinkle/actions/mcp-adapter.ts +179 -4
- package/src/Sprinkle/index.ts +264 -3
- package/src/Sprinkle/schemas.ts +20 -0
package/src/Sprinkle/index.ts
CHANGED
|
@@ -58,10 +58,14 @@ export {
|
|
|
58
58
|
NetworkSchema,
|
|
59
59
|
MultisigScriptModule,
|
|
60
60
|
MultisigScript,
|
|
61
|
+
NativeScriptInputSchema,
|
|
62
|
+
NativeScriptsParam,
|
|
61
63
|
ProviderSettingsSchema,
|
|
62
64
|
WalletSettingsSchema,
|
|
63
65
|
} from "./schemas.js";
|
|
64
66
|
export type { TMultisigScript } from "./schemas.js";
|
|
67
|
+
import type { TMultisigScript } from "./schemas.js";
|
|
68
|
+
import { MultisigScript as MultisigScriptSchema } from "./schemas.js";
|
|
65
69
|
|
|
66
70
|
// Import and re-export type guards
|
|
67
71
|
import {
|
|
@@ -170,6 +174,7 @@ import {
|
|
|
170
174
|
promptAndExecute,
|
|
171
175
|
} from "./actions/index.js";
|
|
172
176
|
import type { AnyAction, IActionContext, IActionResult } from "./actions/index.js";
|
|
177
|
+
import { toNativeScript } from "./actions/index.js";
|
|
173
178
|
export type { IAction, IActionContext, IActionResult, IActionSuccess, IActionFailure, AnyAction } from "./actions/index.js";
|
|
174
179
|
export {
|
|
175
180
|
ActionRegistry,
|
|
@@ -191,7 +196,15 @@ export {
|
|
|
191
196
|
runMcp,
|
|
192
197
|
getBuiltinActions,
|
|
193
198
|
promptAndExecute,
|
|
199
|
+
toNativeScript,
|
|
200
|
+
completeWithScripts,
|
|
194
201
|
} from "./actions/index.js";
|
|
202
|
+
export type { NativeScriptInput } from "./actions/index.js";
|
|
203
|
+
import {
|
|
204
|
+
mintToken,
|
|
205
|
+
simpleSend,
|
|
206
|
+
registerStakeScript,
|
|
207
|
+
} from "./actions/builtin/utility-actions.js";
|
|
195
208
|
|
|
196
209
|
export interface IMenuAction<S extends TSchema> {
|
|
197
210
|
title: string;
|
|
@@ -209,6 +222,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
209
222
|
settings: TExact<S> = {} as TExact<S>;
|
|
210
223
|
type: S;
|
|
211
224
|
defaults: Record<string, unknown> = {};
|
|
225
|
+
addressbook: Record<string, TMultisigScript> = {};
|
|
212
226
|
options: ISprinkleOptions;
|
|
213
227
|
profileId: string = "";
|
|
214
228
|
profileMeta: IProfileMeta = { name: "", createdAt: "", updatedAt: "" };
|
|
@@ -301,6 +315,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
301
315
|
this.profileMeta = parsed.meta;
|
|
302
316
|
this.settings = await this.decryptSettings(parsed.settings as TExact<S>);
|
|
303
317
|
this.defaults = parsed.defaults ?? {};
|
|
318
|
+
this.addressbook = parsed.addressbook ?? {};
|
|
304
319
|
// Update active profile pointer
|
|
305
320
|
fs.writeFileSync(Sprinkle.activeProfilePath(this.storagePath), id, "utf-8");
|
|
306
321
|
}
|
|
@@ -323,6 +338,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
323
338
|
meta: this.profileMeta,
|
|
324
339
|
settings: settingsToSave,
|
|
325
340
|
defaults: this.defaults,
|
|
341
|
+
addressbook: this.addressbook,
|
|
326
342
|
},
|
|
327
343
|
bigIntReplacer,
|
|
328
344
|
2,
|
|
@@ -403,6 +419,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
403
419
|
},
|
|
404
420
|
settings: parsed.settings,
|
|
405
421
|
defaults: parsed.defaults ?? {},
|
|
422
|
+
addressbook: parsed.addressbook ?? {},
|
|
406
423
|
};
|
|
407
424
|
fs.mkdirSync(profilesDir, { recursive: true });
|
|
408
425
|
fs.writeFileSync(
|
|
@@ -487,6 +504,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
487
504
|
meta: { name, description, createdAt: now, updatedAt: now },
|
|
488
505
|
settings: settingsToSave,
|
|
489
506
|
defaults: this.defaults,
|
|
507
|
+
addressbook: this.addressbook,
|
|
490
508
|
},
|
|
491
509
|
bigIntReplacer,
|
|
492
510
|
2,
|
|
@@ -598,6 +616,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
598
616
|
if (!main) {
|
|
599
617
|
choices.push({ name: "Back", value: -1 });
|
|
600
618
|
} else {
|
|
619
|
+
choices.push({ name: "Utilities", value: -6 });
|
|
601
620
|
choices.push({ name: "Settings & Profiles", value: -5 });
|
|
602
621
|
choices.push({ name: "Exit", value: -1 });
|
|
603
622
|
}
|
|
@@ -616,6 +635,74 @@ export class Sprinkle<S extends TSchema> {
|
|
|
616
635
|
return;
|
|
617
636
|
}
|
|
618
637
|
const selection = selectionResult as number;
|
|
638
|
+
if (selection === -6) {
|
|
639
|
+
const utilitiesMenu: IMenu<S> = {
|
|
640
|
+
title: "Utilities",
|
|
641
|
+
items: [
|
|
642
|
+
{
|
|
643
|
+
title: "Mint Token",
|
|
644
|
+
action: async () => {
|
|
645
|
+
const result = await promptAndExecute(this, mintToken);
|
|
646
|
+
if (!result.success) {
|
|
647
|
+
if (result.error.code === "USER_CANCELLED") return;
|
|
648
|
+
console.error(`\nError (${result.error.code}): ${result.error.message}\n`);
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const data = result.data as { txCbor: string; policyId: string; tokenName: string; amount: string };
|
|
652
|
+
console.log(`\nPolicy: ${data.policyId}\nToken: ${data.tokenName}\nAmount: ${data.amount}\n`);
|
|
653
|
+
const blaze = await Sprinkle.GetBlaze(
|
|
654
|
+
(this.settings as Record<string, unknown>).network as TExact<typeof NetworkSchema>,
|
|
655
|
+
(this.settings as Record<string, unknown>).provider as TExact<typeof ProviderSettingsSchema>,
|
|
656
|
+
(this.settings as Record<string, unknown>).wallet as TExact<typeof WalletSettingsSchema>,
|
|
657
|
+
);
|
|
658
|
+
const tx = Core.Transaction.fromCbor(Core.TxCBOR(data.txCbor));
|
|
659
|
+
await this.TxDialog(blaze, tx);
|
|
660
|
+
},
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
title: "Simple Send",
|
|
664
|
+
action: async () => {
|
|
665
|
+
const result = await promptAndExecute(this, simpleSend);
|
|
666
|
+
if (!result.success) {
|
|
667
|
+
if (result.error.code === "USER_CANCELLED") return;
|
|
668
|
+
console.error(`\nError (${result.error.code}): ${result.error.message}\n`);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
const data = result.data as { txCbor: string };
|
|
672
|
+
const blaze = await Sprinkle.GetBlaze(
|
|
673
|
+
(this.settings as Record<string, unknown>).network as TExact<typeof NetworkSchema>,
|
|
674
|
+
(this.settings as Record<string, unknown>).provider as TExact<typeof ProviderSettingsSchema>,
|
|
675
|
+
(this.settings as Record<string, unknown>).wallet as TExact<typeof WalletSettingsSchema>,
|
|
676
|
+
);
|
|
677
|
+
const tx = Core.Transaction.fromCbor(Core.TxCBOR(data.txCbor));
|
|
678
|
+
await this.TxDialog(blaze, tx);
|
|
679
|
+
},
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
title: "Register Stake Script",
|
|
683
|
+
action: async () => {
|
|
684
|
+
const result = await promptAndExecute(this, registerStakeScript);
|
|
685
|
+
if (!result.success) {
|
|
686
|
+
if (result.error.code === "USER_CANCELLED") return;
|
|
687
|
+
console.error(`\nError (${result.error.code}): ${result.error.message}\n`);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const data = result.data as { txCbor: string };
|
|
691
|
+
const blaze = await Sprinkle.GetBlaze(
|
|
692
|
+
(this.settings as Record<string, unknown>).network as TExact<typeof NetworkSchema>,
|
|
693
|
+
(this.settings as Record<string, unknown>).provider as TExact<typeof ProviderSettingsSchema>,
|
|
694
|
+
(this.settings as Record<string, unknown>).wallet as TExact<typeof WalletSettingsSchema>,
|
|
695
|
+
);
|
|
696
|
+
const tx = Core.Transaction.fromCbor(Core.TxCBOR(data.txCbor));
|
|
697
|
+
await this.TxDialog(blaze, tx);
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
],
|
|
701
|
+
};
|
|
702
|
+
await this._showMenu(utilitiesMenu, false, [...path, "Utilities"], true);
|
|
703
|
+
await this._showMenu(menu, main, path, true);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
619
706
|
if (selection === -5) {
|
|
620
707
|
const settingsMenu: IMenu<S> = {
|
|
621
708
|
title: "Settings & Profiles",
|
|
@@ -689,6 +776,114 @@ export class Sprinkle<S extends TSchema> {
|
|
|
689
776
|
await this.deleteProfile();
|
|
690
777
|
},
|
|
691
778
|
},
|
|
779
|
+
{
|
|
780
|
+
title: "Addressbook",
|
|
781
|
+
items: [
|
|
782
|
+
{
|
|
783
|
+
title: "View entries",
|
|
784
|
+
action: async () => {
|
|
785
|
+
const entries = Object.entries(this.addressbook);
|
|
786
|
+
if (entries.length === 0) {
|
|
787
|
+
console.log("Addressbook is empty.");
|
|
788
|
+
} else {
|
|
789
|
+
for (const [name, ms] of entries) {
|
|
790
|
+
const json = JSON.stringify(ms, bigIntReplacer, 2);
|
|
791
|
+
let hashStr = "unknown";
|
|
792
|
+
try {
|
|
793
|
+
hashStr = toNativeScript(ms).hash();
|
|
794
|
+
} catch { /* skip */ }
|
|
795
|
+
console.log(colors.bold(name) + " " + colors.dim(hashStr));
|
|
796
|
+
console.log(json);
|
|
797
|
+
console.log();
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
await selectWithClear({
|
|
801
|
+
message: "Press Enter to continue...",
|
|
802
|
+
choices: [{ name: "Continue", value: "continue" }],
|
|
803
|
+
});
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
title: "Add entry",
|
|
808
|
+
action: async () => {
|
|
809
|
+
const name = await inputCancellable({
|
|
810
|
+
message: "Entry name:",
|
|
811
|
+
validate: (v) =>
|
|
812
|
+
v.trim().length > 0 ? true : "Name cannot be empty",
|
|
813
|
+
});
|
|
814
|
+
if (name === null) return;
|
|
815
|
+
if (this.addressbook[name]) {
|
|
816
|
+
const overwrite = await confirmCancellable({
|
|
817
|
+
message: `Entry "${name}" already exists. Overwrite?`,
|
|
818
|
+
default: false,
|
|
819
|
+
});
|
|
820
|
+
if (!overwrite) return;
|
|
821
|
+
}
|
|
822
|
+
try {
|
|
823
|
+
const script = await this.FillInStruct(MultisigScriptSchema);
|
|
824
|
+
this.addressbook[name] = script as TMultisigScript;
|
|
825
|
+
this.saveSettings();
|
|
826
|
+
console.log(`Added "${name}" to addressbook.`);
|
|
827
|
+
} catch (e) {
|
|
828
|
+
if (e instanceof UserCancelledError) return;
|
|
829
|
+
throw e;
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
title: "Edit entry",
|
|
835
|
+
action: async () => {
|
|
836
|
+
const entries = Object.keys(this.addressbook);
|
|
837
|
+
if (entries.length === 0) {
|
|
838
|
+
console.log("Addressbook is empty.");
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const selected = await selectCancellable({
|
|
842
|
+
message: "Select entry to edit:",
|
|
843
|
+
choices: entries.map((n) => ({ name: n, value: n })),
|
|
844
|
+
});
|
|
845
|
+
if (selected === null) return;
|
|
846
|
+
const editName = selected as string;
|
|
847
|
+
try {
|
|
848
|
+
const updated = await this.EditStruct(
|
|
849
|
+
MultisigScriptSchema,
|
|
850
|
+
this.addressbook[editName] as any,
|
|
851
|
+
);
|
|
852
|
+
this.addressbook[editName] = updated as TMultisigScript;
|
|
853
|
+
this.saveSettings();
|
|
854
|
+
console.log(`Updated "${editName}".`);
|
|
855
|
+
} catch (e) {
|
|
856
|
+
if (e instanceof UserCancelledError) return;
|
|
857
|
+
throw e;
|
|
858
|
+
}
|
|
859
|
+
},
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
title: "Delete entry",
|
|
863
|
+
action: async () => {
|
|
864
|
+
const entries = Object.keys(this.addressbook);
|
|
865
|
+
if (entries.length === 0) {
|
|
866
|
+
console.log("Addressbook is empty.");
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
const delSelected = await selectCancellable({
|
|
870
|
+
message: "Select entry to delete:",
|
|
871
|
+
choices: entries.map((n) => ({ name: n, value: n })),
|
|
872
|
+
});
|
|
873
|
+
if (delSelected === null) return;
|
|
874
|
+
const delName = delSelected as string;
|
|
875
|
+
const confirmed = await confirmCancellable({
|
|
876
|
+
message: `Delete "${delName}"?`,
|
|
877
|
+
default: false,
|
|
878
|
+
});
|
|
879
|
+
if (!confirmed) return;
|
|
880
|
+
delete this.addressbook[delName];
|
|
881
|
+
this.saveSettings();
|
|
882
|
+
console.log(`Deleted "${delName}".`);
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
],
|
|
886
|
+
} as IMenu<S>,
|
|
692
887
|
],
|
|
693
888
|
};
|
|
694
889
|
await this._showMenu(settingsMenu, false, [...path, "Settings & Profiles"], true);
|
|
@@ -869,6 +1064,7 @@ export class Sprinkle<S extends TSchema> {
|
|
|
869
1064
|
meta,
|
|
870
1065
|
settings: initialSettings ?? {},
|
|
871
1066
|
defaults: {},
|
|
1067
|
+
addressbook: {},
|
|
872
1068
|
};
|
|
873
1069
|
|
|
874
1070
|
fs.writeFileSync(
|
|
@@ -1242,9 +1438,58 @@ export class Sprinkle<S extends TSchema> {
|
|
|
1242
1438
|
`Could not resolve type ${type["$ref"]} at ${path.join(".")}`,
|
|
1243
1439
|
);
|
|
1244
1440
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1441
|
+
|
|
1442
|
+
// Addressbook integration for MultisigScript fields
|
|
1443
|
+
if (type["$ref"] === "MultisigScript" && Object.keys(this.addressbook).length > 0) {
|
|
1444
|
+
const sourceChoice = await selectWithClear({
|
|
1445
|
+
message: "Select source for native script:",
|
|
1446
|
+
choices: [
|
|
1447
|
+
{ name: "Enter manually", value: "manual" },
|
|
1448
|
+
{ name: "Select from addressbook", value: "addressbook" },
|
|
1449
|
+
],
|
|
1450
|
+
});
|
|
1451
|
+
if (sourceChoice === null) throw new UserCancelledError();
|
|
1452
|
+
if (sourceChoice === "addressbook") {
|
|
1453
|
+
const entries = Object.entries(this.addressbook);
|
|
1454
|
+
const abChoices = entries.map(([name, ms]) => {
|
|
1455
|
+
let hashStr = "";
|
|
1456
|
+
try { hashStr = " " + colors.dim(toNativeScript(ms).hash()); } catch { /* skip */ }
|
|
1457
|
+
return { name: name + hashStr, value: name };
|
|
1458
|
+
});
|
|
1459
|
+
const selected = await selectWithClear({
|
|
1460
|
+
message: "Select addressbook entry:",
|
|
1461
|
+
choices: abChoices,
|
|
1462
|
+
});
|
|
1463
|
+
if (selected === null) throw new UserCancelledError();
|
|
1464
|
+
return this.addressbook[selected as string] as TExact<U>;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
const result = await this._fillInStruct(resolvedType, path, defs, def) as TExact<U>;
|
|
1469
|
+
|
|
1470
|
+
// Offer to save manually entered MultisigScript to addressbook
|
|
1471
|
+
if (type["$ref"] === "MultisigScript" && result !== undefined) {
|
|
1472
|
+
const shouldSave = await selectWithClear({
|
|
1473
|
+
message: "Save this script to the addressbook?",
|
|
1474
|
+
choices: [
|
|
1475
|
+
{ name: "No", value: false },
|
|
1476
|
+
{ name: "Yes", value: true },
|
|
1477
|
+
],
|
|
1478
|
+
});
|
|
1479
|
+
if (shouldSave) {
|
|
1480
|
+
const entryName = await inputCancellable({
|
|
1481
|
+
message: "Addressbook entry name:",
|
|
1482
|
+
validate: (v) => v.trim().length > 0 ? true : "Name cannot be empty",
|
|
1483
|
+
});
|
|
1484
|
+
if (entryName !== null) {
|
|
1485
|
+
this.addressbook[entryName] = result as TMultisigScript;
|
|
1486
|
+
this.saveSettings();
|
|
1487
|
+
console.log(`Saved "${entryName}" to addressbook.`);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
return result;
|
|
1248
1493
|
}
|
|
1249
1494
|
if (isOptional(type)) {
|
|
1250
1495
|
const pathDisplay = formatPath(path) || "value";
|
|
@@ -1401,6 +1646,22 @@ export class Sprinkle<S extends TSchema> {
|
|
|
1401
1646
|
return BigInt(answer) as TExact<U>;
|
|
1402
1647
|
}
|
|
1403
1648
|
|
|
1649
|
+
if (isBoolean(type)) {
|
|
1650
|
+
const pathDisplay = formatPath(path) || "value";
|
|
1651
|
+
const answer = await selectWithClear({
|
|
1652
|
+
message: Sprinkle.ExtractMessage(type, `${pathDisplay}?`),
|
|
1653
|
+
choices: [
|
|
1654
|
+
{ name: "Yes", value: true },
|
|
1655
|
+
{ name: "No", value: false },
|
|
1656
|
+
],
|
|
1657
|
+
default: def !== undefined ? (def as boolean) : hasDefault(type) ? getDefault(type) : undefined,
|
|
1658
|
+
});
|
|
1659
|
+
if (answer === null) {
|
|
1660
|
+
throw new UserCancelledError();
|
|
1661
|
+
}
|
|
1662
|
+
return answer as TExact<U>;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1404
1665
|
if (isLiteral(type)) {
|
|
1405
1666
|
return type.const as TExact<U>;
|
|
1406
1667
|
}
|
package/src/Sprinkle/schemas.ts
CHANGED
|
@@ -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
|
*/
|