@sundaeswap/sprinkles 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Sprinkle/__tests__/encryption.test.js +20 -8
- package/dist/cjs/Sprinkle/__tests__/encryption.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/enhancements.test.js +41 -16
- package/dist/cjs/Sprinkle/__tests__/enhancements.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +85 -38
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/settings-persistence.test.js +120 -0
- package/dist/cjs/Sprinkle/__tests__/settings-persistence.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/show-menu.test.js +93 -7
- package/dist/cjs/Sprinkle/__tests__/show-menu.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +21 -0
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/cjs/Sprinkle/encryption.js +131 -0
- package/dist/cjs/Sprinkle/encryption.js.map +1 -0
- package/dist/cjs/Sprinkle/index.js +318 -352
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/prompts.js +393 -0
- package/dist/cjs/Sprinkle/prompts.js.map +1 -0
- package/dist/cjs/Sprinkle/schemas.js +97 -0
- package/dist/cjs/Sprinkle/schemas.js.map +1 -0
- package/dist/cjs/Sprinkle/tx-dialog.js +101 -0
- package/dist/cjs/Sprinkle/tx-dialog.js.map +1 -0
- package/dist/cjs/Sprinkle/type-guards.js +42 -0
- package/dist/cjs/Sprinkle/type-guards.js.map +1 -0
- package/dist/cjs/Sprinkle/types.js +49 -0
- package/dist/cjs/Sprinkle/types.js.map +1 -0
- package/dist/cjs/Sprinkle/wallet.js +98 -0
- package/dist/cjs/Sprinkle/wallet.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/encryption.test.js +20 -8
- package/dist/esm/Sprinkle/__tests__/encryption.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/enhancements.test.js +41 -16
- package/dist/esm/Sprinkle/__tests__/enhancements.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +85 -38
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/settings-persistence.test.js +120 -0
- package/dist/esm/Sprinkle/__tests__/settings-persistence.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/show-menu.test.js +94 -8
- package/dist/esm/Sprinkle/__tests__/show-menu.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +21 -0
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/esm/Sprinkle/encryption.js +117 -0
- package/dist/esm/Sprinkle/encryption.js.map +1 -0
- package/dist/esm/Sprinkle/index.js +172 -337
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/prompts.js +385 -0
- package/dist/esm/Sprinkle/prompts.js.map +1 -0
- package/dist/esm/Sprinkle/schemas.js +91 -0
- package/dist/esm/Sprinkle/schemas.js.map +1 -0
- package/dist/esm/Sprinkle/tx-dialog.js +90 -0
- package/dist/esm/Sprinkle/tx-dialog.js.map +1 -0
- package/dist/esm/Sprinkle/type-guards.js +24 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -0
- package/dist/esm/Sprinkle/types.js +42 -0
- package/dist/esm/Sprinkle/types.js.map +1 -0
- package/dist/esm/Sprinkle/wallet.js +90 -0
- package/dist/esm/Sprinkle/wallet.js.map +1 -0
- package/dist/types/Sprinkle/encryption.d.ts +43 -0
- package/dist/types/Sprinkle/encryption.d.ts.map +1 -0
- package/dist/types/Sprinkle/index.d.ts +13 -174
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/prompts.d.ts +94 -0
- package/dist/types/Sprinkle/prompts.d.ts.map +1 -0
- package/dist/types/Sprinkle/schemas.d.ts +125 -0
- package/dist/types/Sprinkle/schemas.d.ts.map +1 -0
- package/dist/types/Sprinkle/tx-dialog.d.ts +37 -0
- package/dist/types/Sprinkle/tx-dialog.d.ts.map +1 -0
- package/dist/types/Sprinkle/type-guards.d.ts +22 -0
- package/dist/types/Sprinkle/type-guards.d.ts.map +1 -0
- package/dist/types/Sprinkle/types.d.ts +62 -0
- package/dist/types/Sprinkle/types.d.ts.map +1 -0
- package/dist/types/Sprinkle/wallet.d.ts +27 -0
- package/dist/types/Sprinkle/wallet.d.ts.map +1 -0
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Sprinkle/__tests__/encryption.test.ts +21 -8
- package/src/Sprinkle/__tests__/enhancements.test.ts +41 -15
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +104 -38
- package/src/Sprinkle/__tests__/settings-persistence.test.ts +108 -0
- package/src/Sprinkle/__tests__/show-menu.test.ts +96 -8
- package/src/Sprinkle/__tests__/tx-dialog.test.ts +21 -0
- package/src/Sprinkle/encryption.ts +130 -0
- package/src/Sprinkle/index.ts +265 -478
- package/src/Sprinkle/prompts.ts +481 -0
- package/src/Sprinkle/schemas.ts +111 -0
- package/src/Sprinkle/tx-dialog.ts +100 -0
- package/src/Sprinkle/type-guards.ts +51 -0
- package/src/Sprinkle/types.ts +73 -0
- package/src/Sprinkle/wallet.ts +133 -0
|
@@ -4,18 +4,159 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
var _exportNames = {
|
|
7
|
+
Sprinkle: true,
|
|
8
|
+
UserCancelledError: true,
|
|
7
9
|
NetworkSchema: true,
|
|
8
10
|
MultisigScriptModule: true,
|
|
9
11
|
MultisigScript: true,
|
|
10
12
|
ProviderSettingsSchema: true,
|
|
11
13
|
WalletSettingsSchema: true,
|
|
12
|
-
|
|
14
|
+
isOptional: true,
|
|
15
|
+
isImport: true,
|
|
16
|
+
isArray: true,
|
|
17
|
+
isBigInt: true,
|
|
18
|
+
isLiteral: true,
|
|
19
|
+
isObject: true,
|
|
20
|
+
isRef: true,
|
|
21
|
+
isString: true,
|
|
22
|
+
isThis: true,
|
|
23
|
+
isTuple: true,
|
|
24
|
+
isUnion: true,
|
|
25
|
+
isSensitive: true,
|
|
26
|
+
GetProvider: true,
|
|
27
|
+
GetWallet: true,
|
|
28
|
+
GetBlaze: true
|
|
13
29
|
};
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
Object.defineProperty(exports, "GetBlaze", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _wallet.GetBlaze;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "GetProvider", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _wallet.GetProvider;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "GetWallet", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _wallet.GetWallet;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "MultisigScript", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _schemas.MultisigScript;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "MultisigScriptModule", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _schemas.MultisigScriptModule;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "NetworkSchema", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _schemas.NetworkSchema;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "ProviderSettingsSchema", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _schemas.ProviderSettingsSchema;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
exports.Sprinkle = void 0;
|
|
73
|
+
Object.defineProperty(exports, "UserCancelledError", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get: function () {
|
|
76
|
+
return _types.UserCancelledError;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
Object.defineProperty(exports, "WalletSettingsSchema", {
|
|
80
|
+
enumerable: true,
|
|
81
|
+
get: function () {
|
|
82
|
+
return _schemas.WalletSettingsSchema;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
Object.defineProperty(exports, "isArray", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
get: function () {
|
|
88
|
+
return _typeGuards.isArray;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(exports, "isBigInt", {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
get: function () {
|
|
94
|
+
return _typeGuards.isBigInt;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(exports, "isImport", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
get: function () {
|
|
100
|
+
return _typeGuards.isImport;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
Object.defineProperty(exports, "isLiteral", {
|
|
104
|
+
enumerable: true,
|
|
105
|
+
get: function () {
|
|
106
|
+
return _typeGuards.isLiteral;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
Object.defineProperty(exports, "isObject", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function () {
|
|
112
|
+
return _typeGuards.isObject;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
Object.defineProperty(exports, "isOptional", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: function () {
|
|
118
|
+
return _typeGuards.isOptional;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
Object.defineProperty(exports, "isRef", {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
get: function () {
|
|
124
|
+
return _typeGuards.isRef;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
Object.defineProperty(exports, "isSensitive", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
get: function () {
|
|
130
|
+
return _typeGuards.isSensitive;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(exports, "isString", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function () {
|
|
136
|
+
return _typeGuards.isString;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
Object.defineProperty(exports, "isThis", {
|
|
140
|
+
enumerable: true,
|
|
141
|
+
get: function () {
|
|
142
|
+
return _typeGuards.isThis;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(exports, "isTuple", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function () {
|
|
148
|
+
return _typeGuards.isTuple;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
Object.defineProperty(exports, "isUnion", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
get: function () {
|
|
154
|
+
return _typeGuards.isUnion;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
16
157
|
var _sdk = require("@blaze-cardano/sdk");
|
|
17
158
|
var _core = require("@blaze-cardano/core");
|
|
18
|
-
var _prompts = require("
|
|
159
|
+
var _prompts = require("./prompts.js");
|
|
19
160
|
var _typebox = require("@sinclair/typebox");
|
|
20
161
|
Object.keys(_typebox).forEach(function (key) {
|
|
21
162
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -30,102 +171,22 @@ Object.keys(_typebox).forEach(function (key) {
|
|
|
30
171
|
});
|
|
31
172
|
var fs = _interopRequireWildcard(require("fs"));
|
|
32
173
|
var path = _interopRequireWildcard(require("path"));
|
|
174
|
+
var _types = require("./types.js");
|
|
175
|
+
var _schemas = require("./schemas.js");
|
|
176
|
+
var _typeGuards = require("./type-guards.js");
|
|
177
|
+
var _wallet = require("./wallet.js");
|
|
178
|
+
var _encryption = require("./encryption.js");
|
|
179
|
+
var _txDialog = require("./tx-dialog.js");
|
|
33
180
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
34
181
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
35
182
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
36
|
-
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
// const isNumber = (t: TSchema): t is TNumber => t[Kind] === "Number";
|
|
44
|
-
const isObject = t => t[_typebox.Kind] === "Object";
|
|
45
|
-
// const isRecord = (t: TSchema): t is TRecord => t[Kind] === "Record";
|
|
46
|
-
const isRef = t => t[_typebox.Kind] === "Ref";
|
|
47
|
-
const isString = t => t[_typebox.Kind] === "String";
|
|
48
|
-
const isThis = t => t[_typebox.Kind] === "This";
|
|
49
|
-
const isTuple = t => t[_typebox.Kind] === "Tuple";
|
|
50
|
-
const isUnion = t => t[_typebox.Kind] === "Union";
|
|
51
|
-
// const isAny = (t: TSchema): t is TAny => t[Kind] === "Any";
|
|
52
|
-
|
|
53
|
-
const isSensitive = t => isString(t) && t.sensitive === true;
|
|
54
|
-
const NetworkSchema = exports.NetworkSchema = _typebox.Type.Union([_typebox.Type.Literal("mainnet"), _typebox.Type.Literal("preview"), _typebox.Type.Literal("preprod")]);
|
|
55
|
-
const MultisigScriptModule = exports.MultisigScriptModule = _typebox.Type.Module({
|
|
56
|
-
MultisigScript: _typebox.Type.Union([_typebox.Type.Object({
|
|
57
|
-
Signature: _typebox.Type.Object({
|
|
58
|
-
key_hash: _typebox.Type.String()
|
|
59
|
-
}, {
|
|
60
|
-
ctor: 0n
|
|
61
|
-
})
|
|
62
|
-
}), _typebox.Type.Object({
|
|
63
|
-
AllOf: _typebox.Type.Object({
|
|
64
|
-
scripts: _typebox.Type.Array(_typebox.Type.Ref("MultisigScript"))
|
|
65
|
-
}, {
|
|
66
|
-
ctor: 1n
|
|
67
|
-
})
|
|
68
|
-
}), _typebox.Type.Object({
|
|
69
|
-
AnyOf: _typebox.Type.Object({
|
|
70
|
-
scripts: _typebox.Type.Array(_typebox.Type.Ref("MultisigScript"))
|
|
71
|
-
}, {
|
|
72
|
-
ctor: 2n
|
|
73
|
-
})
|
|
74
|
-
}), _typebox.Type.Object({
|
|
75
|
-
AtLeast: _typebox.Type.Object({
|
|
76
|
-
required: _typebox.Type.BigInt(),
|
|
77
|
-
scripts: _typebox.Type.Array(_typebox.Type.Ref("MultisigScript"))
|
|
78
|
-
}, {
|
|
79
|
-
ctor: 3n
|
|
80
|
-
})
|
|
81
|
-
}), _typebox.Type.Object({
|
|
82
|
-
Before: _typebox.Type.Object({
|
|
83
|
-
time: _typebox.Type.BigInt()
|
|
84
|
-
}, {
|
|
85
|
-
ctor: 4n
|
|
86
|
-
})
|
|
87
|
-
}), _typebox.Type.Object({
|
|
88
|
-
After: _typebox.Type.Object({
|
|
89
|
-
time: _typebox.Type.BigInt()
|
|
90
|
-
}, {
|
|
91
|
-
ctor: 5n
|
|
92
|
-
})
|
|
93
|
-
}), _typebox.Type.Object({
|
|
94
|
-
Script: _typebox.Type.Object({
|
|
95
|
-
script_hash: _typebox.Type.String()
|
|
96
|
-
}, {
|
|
97
|
-
ctor: 6n
|
|
98
|
-
})
|
|
99
|
-
})])
|
|
100
|
-
});
|
|
101
|
-
const MultisigScript = exports.MultisigScript = MultisigScriptModule.Import("MultisigScript");
|
|
102
|
-
const ProviderSettingsSchema = exports.ProviderSettingsSchema = _typebox.Type.Union([_typebox.Type.Object({
|
|
103
|
-
type: _typebox.Type.Literal("blockfrost"),
|
|
104
|
-
projectId: _typebox.Type.String({
|
|
105
|
-
minLength: 1,
|
|
106
|
-
title: "Blockfrost Project ID"
|
|
107
|
-
})
|
|
108
|
-
}), _typebox.Type.Object({
|
|
109
|
-
type: _typebox.Type.Literal("maestro"),
|
|
110
|
-
apiKey: _typebox.Type.String({
|
|
111
|
-
minLength: 1,
|
|
112
|
-
title: "Maestro API Key"
|
|
113
|
-
})
|
|
114
|
-
})]);
|
|
115
|
-
const WalletSettingsSchema = exports.WalletSettingsSchema = _typebox.Type.Union([_typebox.Type.Object({
|
|
116
|
-
type: _typebox.Type.Literal("hot"),
|
|
117
|
-
privateKey: _typebox.Type.String({
|
|
118
|
-
minLength: 1,
|
|
119
|
-
title: "Hot Wallet Private Key",
|
|
120
|
-
sensitive: true
|
|
121
|
-
})
|
|
122
|
-
}), _typebox.Type.Object({
|
|
123
|
-
type: _typebox.Type.Literal("cold"),
|
|
124
|
-
address: _typebox.Type.String({
|
|
125
|
-
minLength: 1,
|
|
126
|
-
title: "Cold Wallet Address"
|
|
127
|
-
})
|
|
128
|
-
})]);
|
|
183
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // Re-export types from types.ts
|
|
184
|
+
// Re-export schemas from schemas.ts
|
|
185
|
+
// Import and re-export type guards
|
|
186
|
+
// Import schemas for use in this file
|
|
187
|
+
// Import and re-export wallet utilities
|
|
188
|
+
// Import encryption utilities
|
|
189
|
+
// Import tx-dialog utilities
|
|
129
190
|
class Sprinkle {
|
|
130
191
|
constructor(type, storagePath, options) {
|
|
131
192
|
_defineProperty(this, "storagePath", void 0);
|
|
@@ -144,6 +205,16 @@ class Sprinkle {
|
|
|
144
205
|
this.options = options ?? {};
|
|
145
206
|
}
|
|
146
207
|
|
|
208
|
+
// --- Current Profile Accessor ---
|
|
209
|
+
|
|
210
|
+
get currentProfile() {
|
|
211
|
+
if (!this.profileId) return null;
|
|
212
|
+
return {
|
|
213
|
+
id: this.profileId,
|
|
214
|
+
...this.profileMeta
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
147
218
|
// --- Profile path helpers ---
|
|
148
219
|
|
|
149
220
|
static sanitizeProfileId(name) {
|
|
@@ -222,32 +293,42 @@ class Sprinkle {
|
|
|
222
293
|
meta: this.profileMeta,
|
|
223
294
|
settings: settingsToSave,
|
|
224
295
|
defaults: this.defaults
|
|
225
|
-
},
|
|
296
|
+
}, _encryption.bigIntReplacer, 2);
|
|
226
297
|
fs.writeFileSync(filePath, jsonContent, "utf-8");
|
|
227
298
|
}
|
|
228
299
|
async promptProfileMeta(defaultName, defaultDescription) {
|
|
229
|
-
const name = await (0, _prompts.
|
|
300
|
+
const name = await (0, _prompts.inputCancellable)({
|
|
230
301
|
message: "Profile name:",
|
|
231
302
|
default: defaultName,
|
|
232
303
|
validate: v => v.trim().length > 0 ? true : "Name cannot be empty"
|
|
233
304
|
});
|
|
234
|
-
|
|
305
|
+
if (name === null) return null; // User cancelled
|
|
306
|
+
const description = await (0, _prompts.inputCancellable)({
|
|
235
307
|
message: "Profile description (optional):",
|
|
236
308
|
default: defaultDescription ?? ""
|
|
237
309
|
});
|
|
310
|
+
if (description === null) return null; // User cancelled
|
|
238
311
|
return {
|
|
239
312
|
name,
|
|
240
313
|
description: description || undefined
|
|
241
314
|
};
|
|
242
315
|
}
|
|
243
316
|
async createProfile() {
|
|
317
|
+
const result = await this.promptProfileMeta();
|
|
318
|
+
if (result === null) return; // User cancelled
|
|
244
319
|
const {
|
|
245
320
|
name,
|
|
246
321
|
description
|
|
247
|
-
} =
|
|
322
|
+
} = result;
|
|
248
323
|
const profilesDir = Sprinkle.profilesDir(this.storagePath);
|
|
249
324
|
const id = Sprinkle.findAvailableId(profilesDir, Sprinkle.sanitizeProfileId(name));
|
|
250
325
|
const now = new Date().toISOString();
|
|
326
|
+
|
|
327
|
+
// Snapshot current state in case we need to restore on cancellation
|
|
328
|
+
const prevProfileId = this.profileId;
|
|
329
|
+
const prevProfileMeta = this.profileMeta;
|
|
330
|
+
const prevDefaults = this.defaults;
|
|
331
|
+
const prevSettings = this.settings;
|
|
251
332
|
this.profileId = id;
|
|
252
333
|
this.profileMeta = {
|
|
253
334
|
name,
|
|
@@ -256,7 +337,19 @@ class Sprinkle {
|
|
|
256
337
|
updatedAt: now
|
|
257
338
|
};
|
|
258
339
|
this.defaults = {};
|
|
259
|
-
|
|
340
|
+
try {
|
|
341
|
+
this.settings = await this.FillInStruct(this.type);
|
|
342
|
+
} catch (e) {
|
|
343
|
+
// Restore previous state on cancellation
|
|
344
|
+
if (e instanceof _types.UserCancelledError) {
|
|
345
|
+
this.profileId = prevProfileId;
|
|
346
|
+
this.profileMeta = prevProfileMeta;
|
|
347
|
+
this.defaults = prevDefaults;
|
|
348
|
+
this.settings = prevSettings;
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
throw e;
|
|
352
|
+
}
|
|
260
353
|
this.saveProfile();
|
|
261
354
|
fs.writeFileSync(Sprinkle.activeProfilePath(this.storagePath), id, "utf-8");
|
|
262
355
|
}
|
|
@@ -281,7 +374,7 @@ class Sprinkle {
|
|
|
281
374
|
fs.mkdirSync(profilesDir, {
|
|
282
375
|
recursive: true
|
|
283
376
|
});
|
|
284
|
-
fs.writeFileSync(Sprinkle.profilePath(this.storagePath, "default"), JSON.stringify(profileData,
|
|
377
|
+
fs.writeFileSync(Sprinkle.profilePath(this.storagePath, "default"), JSON.stringify(profileData, _encryption.bigIntReplacer, 2), "utf-8");
|
|
285
378
|
fs.writeFileSync(Sprinkle.activeProfilePath(this.storagePath), "default", "utf-8");
|
|
286
379
|
// Backup legacy file
|
|
287
380
|
fs.renameSync(legacyPath, `${legacyPath}.bak`);
|
|
@@ -318,23 +411,26 @@ class Sprinkle {
|
|
|
318
411
|
}
|
|
319
412
|
async selectProfile(profiles) {
|
|
320
413
|
const available = profiles ?? this.scanProfiles();
|
|
321
|
-
const selection = await (0, _prompts.
|
|
414
|
+
const selection = await (0, _prompts.selectCancellable)({
|
|
322
415
|
message: "Select a profile:",
|
|
323
416
|
choices: available.map(p => ({
|
|
324
417
|
name: p.meta.description ? `${p.meta.name} - ${p.meta.description}` : p.meta.name,
|
|
325
418
|
value: p.id
|
|
326
419
|
}))
|
|
327
420
|
});
|
|
421
|
+
if (selection === null) return; // User cancelled
|
|
328
422
|
await this.loadProfile(selection);
|
|
329
423
|
}
|
|
330
424
|
|
|
331
425
|
// --- Profile management (CRUD) ---
|
|
332
426
|
|
|
333
427
|
async duplicateProfile() {
|
|
428
|
+
const result = await this.promptProfileMeta(`${this.profileMeta.name} (copy)`, this.profileMeta.description);
|
|
429
|
+
if (result === null) return; // User cancelled
|
|
334
430
|
const {
|
|
335
431
|
name,
|
|
336
432
|
description
|
|
337
|
-
} =
|
|
433
|
+
} = result;
|
|
338
434
|
const profilesDir = Sprinkle.profilesDir(this.storagePath);
|
|
339
435
|
const id = Sprinkle.findAvailableId(profilesDir, Sprinkle.sanitizeProfileId(name));
|
|
340
436
|
const now = new Date().toISOString();
|
|
@@ -349,15 +445,17 @@ class Sprinkle {
|
|
|
349
445
|
},
|
|
350
446
|
settings: settingsToSave,
|
|
351
447
|
defaults: this.defaults
|
|
352
|
-
},
|
|
448
|
+
}, _encryption.bigIntReplacer, 2);
|
|
353
449
|
fs.writeFileSync(path.join(profilesDir, `${id}.json`), jsonContent, "utf-8");
|
|
354
450
|
console.log(`Profile "${name}" created as a copy.`);
|
|
355
451
|
}
|
|
356
452
|
async renameProfile() {
|
|
453
|
+
const result = await this.promptProfileMeta(this.profileMeta.name, this.profileMeta.description);
|
|
454
|
+
if (result === null) return; // User cancelled
|
|
357
455
|
const {
|
|
358
456
|
name,
|
|
359
457
|
description
|
|
360
|
-
} =
|
|
458
|
+
} = result;
|
|
361
459
|
const newId = Sprinkle.sanitizeProfileId(name);
|
|
362
460
|
const oldId = this.profileId;
|
|
363
461
|
this.profileMeta.name = name;
|
|
@@ -385,25 +483,26 @@ class Sprinkle {
|
|
|
385
483
|
console.log("Cannot delete the only profile.");
|
|
386
484
|
return;
|
|
387
485
|
}
|
|
388
|
-
const toDelete = await (0, _prompts.
|
|
486
|
+
const toDelete = await (0, _prompts.selectCancellable)({
|
|
389
487
|
message: "Select a profile to delete:",
|
|
390
|
-
choices:
|
|
488
|
+
choices: others.map(p => ({
|
|
391
489
|
name: p.meta.description ? `${p.meta.name} - ${p.meta.description}` : p.meta.name,
|
|
392
490
|
value: p.id
|
|
393
|
-
}))
|
|
394
|
-
name: "Cancel",
|
|
395
|
-
value: "__cancel__"
|
|
396
|
-
}]
|
|
491
|
+
}))
|
|
397
492
|
});
|
|
398
|
-
if (toDelete ===
|
|
399
|
-
|
|
400
|
-
const
|
|
401
|
-
|
|
493
|
+
if (toDelete === null) return; // User cancelled
|
|
494
|
+
|
|
495
|
+
const profileId = toDelete;
|
|
496
|
+
const profileToDelete = others.find(p => p.id === profileId);
|
|
497
|
+
const confirmed = await (0, _prompts.confirmCancellable)({
|
|
498
|
+
message: `Delete profile "${profileToDelete?.meta.name ?? profileId}"? This cannot be undone.`,
|
|
402
499
|
default: false
|
|
403
500
|
});
|
|
501
|
+
if (confirmed === null) return; // User cancelled
|
|
502
|
+
|
|
404
503
|
if (confirmed) {
|
|
405
|
-
fs.unlinkSync(Sprinkle.profilePath(this.storagePath,
|
|
406
|
-
console.log(`Profile "${profileToDelete?.meta.name ??
|
|
504
|
+
fs.unlinkSync(Sprinkle.profilePath(this.storagePath, profileId));
|
|
505
|
+
console.log(`Profile "${profileToDelete?.meta.name ?? profileId}" deleted.`);
|
|
407
506
|
}
|
|
408
507
|
}
|
|
409
508
|
|
|
@@ -444,14 +543,24 @@ class Sprinkle {
|
|
|
444
543
|
value: -1
|
|
445
544
|
});
|
|
446
545
|
}
|
|
447
|
-
const
|
|
546
|
+
const selectionResult = await (0, _prompts.selectCancellable)({
|
|
448
547
|
message: "Select an option:",
|
|
449
548
|
choices: choices
|
|
450
549
|
});
|
|
550
|
+
// Handle escape (null) as Back
|
|
551
|
+
if (selectionResult === null) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const selection = selectionResult;
|
|
451
555
|
if (selection === -5) {
|
|
452
556
|
const settingsMenu = {
|
|
453
557
|
title: "Settings & Profiles",
|
|
454
558
|
items: [{
|
|
559
|
+
title: "View settings",
|
|
560
|
+
action: async () => {
|
|
561
|
+
console.log(JSON.stringify(this.getDisplaySettings(), _encryption.bigIntReplacer, 2));
|
|
562
|
+
}
|
|
563
|
+
}, {
|
|
455
564
|
title: "Edit settings",
|
|
456
565
|
action: async () => {
|
|
457
566
|
this.settings = await this.EditStruct(this.type, this.settings);
|
|
@@ -519,40 +628,13 @@ class Sprinkle {
|
|
|
519
628
|
return sprinkle;
|
|
520
629
|
}
|
|
521
630
|
static async GetProvider(network, settings) {
|
|
522
|
-
|
|
523
|
-
case "blockfrost":
|
|
524
|
-
return new _query.Blockfrost({
|
|
525
|
-
network: `cardano-${network}`,
|
|
526
|
-
projectId: settings.projectId
|
|
527
|
-
});
|
|
528
|
-
case "maestro":
|
|
529
|
-
// Dynamic import - Maestro may or may not be exported depending on @blaze-cardano/query version
|
|
530
|
-
const queryModule = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/query")));
|
|
531
|
-
if (!queryModule.Maestro) {
|
|
532
|
-
throw new Error("Maestro is not available in the installed version of @blaze-cardano/query. Please install a version that includes Maestro support.");
|
|
533
|
-
}
|
|
534
|
-
return new queryModule.Maestro({
|
|
535
|
-
network: network,
|
|
536
|
-
apiKey: settings.apiKey
|
|
537
|
-
});
|
|
538
|
-
default:
|
|
539
|
-
throw new Error("Invalid provider type");
|
|
540
|
-
}
|
|
631
|
+
return (0, _wallet.GetProvider)(network, settings);
|
|
541
632
|
}
|
|
542
633
|
static async GetWallet(settings, provider) {
|
|
543
|
-
|
|
544
|
-
case "hot":
|
|
545
|
-
return _sdk.HotWallet.fromMasterkey(_sdk.Core.Bip32PrivateKeyHex(settings.privateKey), provider, provider.network);
|
|
546
|
-
case "cold":
|
|
547
|
-
return new _sdk.ColdWallet(_sdk.Core.Address.fromBech32(settings.address), provider.network, provider);
|
|
548
|
-
default:
|
|
549
|
-
throw new Error("Invalid wallet type");
|
|
550
|
-
}
|
|
634
|
+
return (0, _wallet.GetWallet)(settings, provider);
|
|
551
635
|
}
|
|
552
636
|
static async GetBlaze(network, providerSettings, walletSettings) {
|
|
553
|
-
|
|
554
|
-
const wallet = await Sprinkle.GetWallet(walletSettings, provider);
|
|
555
|
-
return _sdk.Blaze.from(provider, wallet);
|
|
637
|
+
return (0, _wallet.GetBlaze)(network, providerSettings, walletSettings);
|
|
556
638
|
}
|
|
557
639
|
|
|
558
640
|
/**
|
|
@@ -561,30 +643,10 @@ class Sprinkle {
|
|
|
561
643
|
* @returns The Bip32PrivateKey hex string for storage
|
|
562
644
|
*/
|
|
563
645
|
static async generateWalletFromMnemonic() {
|
|
564
|
-
|
|
565
|
-
const words = mnemonic.split(" ");
|
|
566
|
-
console.log("\n=== NEW WALLET GENERATED ===\n");
|
|
567
|
-
console.log("IMPORTANT: Save these 24 words in a secure location.");
|
|
568
|
-
console.log("This is the ONLY way to recover your wallet.\n");
|
|
569
|
-
|
|
570
|
-
// Display in 4 columns
|
|
571
|
-
for (let i = 0; i < 6; i++) {
|
|
572
|
-
console.log(`${(i + 1).toString().padStart(2)}. ${words[i].padEnd(12)} ` + `${(i + 7).toString().padStart(2)}. ${words[i + 6].padEnd(12)} ` + `${(i + 13).toString().padStart(2)}. ${words[i + 12].padEnd(12)} ` + `${(i + 19).toString().padStart(2)}. ${words[i + 18]}`);
|
|
573
|
-
}
|
|
574
|
-
console.log("");
|
|
575
|
-
const confirmed = await (0, _prompts.confirm)({
|
|
576
|
-
message: "Have you saved your recovery phrase?",
|
|
577
|
-
default: false
|
|
578
|
-
});
|
|
579
|
-
if (!confirmed) {
|
|
580
|
-
throw new Error("Wallet generation cancelled - recovery phrase not saved");
|
|
581
|
-
}
|
|
582
|
-
const entropy = _sdk.Core.mnemonicToEntropy(mnemonic, _core.wordlist);
|
|
583
|
-
const masterKey = _sdk.Core.Bip32PrivateKey.fromBip39Entropy(Buffer.from(entropy), "");
|
|
584
|
-
return masterKey.hex();
|
|
646
|
+
return (0, _wallet.generateWalletFromMnemonic)();
|
|
585
647
|
}
|
|
586
648
|
static async SearchSelect(opts) {
|
|
587
|
-
return (0, _prompts.
|
|
649
|
+
return (0, _prompts.searchCancellable)(opts);
|
|
588
650
|
}
|
|
589
651
|
static SettingsPath(storagePath) {
|
|
590
652
|
return `${storagePath}${path.sep}settings.json`;
|
|
@@ -608,155 +670,21 @@ class Sprinkle {
|
|
|
608
670
|
}
|
|
609
671
|
}
|
|
610
672
|
static bigIntReviver(key, value) {
|
|
611
|
-
|
|
612
|
-
return BigInt(value.slice(0, -1));
|
|
613
|
-
}
|
|
614
|
-
return value;
|
|
615
|
-
}
|
|
616
|
-
static bigIntReplacer(_key, value) {
|
|
617
|
-
return typeof value === "bigint" ? `${value.toString()}n` : value;
|
|
618
|
-
}
|
|
619
|
-
static collectSensitivePaths(type, prefix = "") {
|
|
620
|
-
const paths = [];
|
|
621
|
-
if (isObject(type)) {
|
|
622
|
-
const fields = type["properties"];
|
|
623
|
-
for (const [field, fieldType] of Object.entries(fields)) {
|
|
624
|
-
const fieldPath = prefix ? `${prefix}.${field}` : field;
|
|
625
|
-
if (isSensitive(fieldType)) {
|
|
626
|
-
paths.push(fieldPath);
|
|
627
|
-
}
|
|
628
|
-
paths.push(...Sprinkle.collectSensitivePaths(fieldType, fieldPath));
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
if (isUnion(type)) {
|
|
632
|
-
for (const variant of type.anyOf) {
|
|
633
|
-
paths.push(...Sprinkle.collectSensitivePaths(variant, prefix));
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return paths;
|
|
637
|
-
}
|
|
638
|
-
static getNestedValue(obj, path) {
|
|
639
|
-
return path.split(".").reduce((o, k) => o?.[k], obj);
|
|
640
|
-
}
|
|
641
|
-
static setNestedValue(obj, path, value) {
|
|
642
|
-
const keys = path.split(".");
|
|
643
|
-
const last = keys.pop();
|
|
644
|
-
const parent = keys.reduce((o, k) => o?.[k], obj);
|
|
645
|
-
if (parent && typeof parent === "object") {
|
|
646
|
-
parent[last] = value;
|
|
647
|
-
}
|
|
673
|
+
return (0, _encryption.bigIntReviver)(key, value);
|
|
648
674
|
}
|
|
649
675
|
encryptSettings(settings) {
|
|
650
676
|
if (!this.options.encryption) return settings;
|
|
651
|
-
|
|
652
|
-
const sensitivePaths = Sprinkle.collectSensitivePaths(this.type);
|
|
653
|
-
for (const p of sensitivePaths) {
|
|
654
|
-
const value = Sprinkle.getNestedValue(clone, p);
|
|
655
|
-
if (typeof value === "string" && value.length > 0) {
|
|
656
|
-
Sprinkle.setNestedValue(clone, p, this.options.encryption.encrypt(value));
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
return clone;
|
|
677
|
+
return (0, _encryption.encryptSensitiveFields)(settings, this.type, this.options.encryption);
|
|
660
678
|
}
|
|
661
679
|
async decryptSettings(settings) {
|
|
662
680
|
if (!this.options.encryption) return settings;
|
|
663
|
-
|
|
664
|
-
const sensitivePaths = Sprinkle.collectSensitivePaths(this.type);
|
|
665
|
-
for (const p of sensitivePaths) {
|
|
666
|
-
const value = Sprinkle.getNestedValue(clone, p);
|
|
667
|
-
if (typeof value === "string" && value.length > 0) {
|
|
668
|
-
Sprinkle.setNestedValue(clone, p, await this.options.encryption.decrypt(value));
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return clone;
|
|
681
|
+
return (0, _encryption.decryptSensitiveFields)(settings, this.type, this.options.encryption);
|
|
672
682
|
}
|
|
673
683
|
saveSettings() {
|
|
674
684
|
this.saveProfile();
|
|
675
685
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* Get the payment key hash from a HotWallet's first address
|
|
681
|
-
*/
|
|
682
|
-
async getWalletPaymentKeyHash(wallet) {
|
|
683
|
-
try {
|
|
684
|
-
const addresses = await wallet.getUsedAddresses();
|
|
685
|
-
const address = addresses[0];
|
|
686
|
-
if (!address) return null;
|
|
687
|
-
const paymentCredential = address.asBase()?.getPaymentCredential();
|
|
688
|
-
return paymentCredential?.hash?.toString() ?? null;
|
|
689
|
-
} catch {
|
|
690
|
-
return null;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Count the number of vkey signatures in a transaction's witness set
|
|
696
|
-
*/
|
|
697
|
-
countSignatures(tx) {
|
|
698
|
-
const vkeys = tx.witnessSet().vkeys();
|
|
699
|
-
return vkeys ? vkeys.size() : 0;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
/**
|
|
703
|
-
* Check if a specific public key has already signed the transaction
|
|
704
|
-
* Compares by vkey (public key bytes)
|
|
705
|
-
*/
|
|
706
|
-
hasVkeySigned(tx, vkeyHex) {
|
|
707
|
-
const vkeys = tx.witnessSet().vkeys();
|
|
708
|
-
if (!vkeys) return false;
|
|
709
|
-
const vkeyArray = vkeys.toCore();
|
|
710
|
-
return vkeyArray.some(([vkey]) => vkey === vkeyHex);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Get the list of required signer key hashes from the transaction body
|
|
715
|
-
*/
|
|
716
|
-
getRequiredSigners(tx) {
|
|
717
|
-
const requiredSigners = tx.body().requiredSigners();
|
|
718
|
-
if (!requiredSigners) return [];
|
|
719
|
-
return Array.from(requiredSigners.values()).map(s => s.toString());
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
/**
|
|
723
|
-
* Compute the transaction body hash for display
|
|
724
|
-
*/
|
|
725
|
-
getTxBodyHash(tx) {
|
|
726
|
-
const bodyCbor = tx.body().toCbor();
|
|
727
|
-
return (0, _core.blake2b_256)(bodyCbor);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
/**
|
|
731
|
-
* Format a hash for display: first 8 chars + ... + last 8 chars
|
|
732
|
-
*/
|
|
733
|
-
formatHash(hash) {
|
|
734
|
-
if (hash.length <= 20) return hash;
|
|
735
|
-
return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* Merge signatures from source transaction into target transaction.
|
|
740
|
-
* Prevents duplicate signatures by comparing vkey (public key).
|
|
741
|
-
* Returns the count of newly added signatures.
|
|
742
|
-
*/
|
|
743
|
-
mergeSignatures(target, source) {
|
|
744
|
-
const targetWs = target.witnessSet();
|
|
745
|
-
const sourceWs = source.witnessSet();
|
|
746
|
-
const targetVkeys = targetWs.vkeys()?.toCore() ?? [];
|
|
747
|
-
const sourceVkeys = sourceWs.vkeys()?.toCore() ?? [];
|
|
748
|
-
|
|
749
|
-
// Find vkeys in source that aren't in target (by comparing public key)
|
|
750
|
-
const existingPubKeys = new Set(targetVkeys.map(([vkey]) => vkey));
|
|
751
|
-
const newVkeys = sourceVkeys.filter(([vkey]) => !existingPubKeys.has(vkey));
|
|
752
|
-
if (newVkeys.length === 0) {
|
|
753
|
-
return 0;
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
// Merge the new vkeys into target
|
|
757
|
-
targetWs.setVkeys(_core.CborSet.fromCore([...targetVkeys, ...newVkeys], _core.VkeyWitness.fromCore));
|
|
758
|
-
target.setWitnessSet(targetWs);
|
|
759
|
-
return newVkeys.length;
|
|
686
|
+
getDisplaySettings() {
|
|
687
|
+
return (0, _encryption.maskSensitiveFields)(this.settings, this.type);
|
|
760
688
|
}
|
|
761
689
|
async TxDialog(blaze, tx, opts) {
|
|
762
690
|
let currentTx = tx;
|
|
@@ -784,16 +712,16 @@ class Sprinkle {
|
|
|
784
712
|
}
|
|
785
713
|
while (true) {
|
|
786
714
|
// Display transaction status
|
|
787
|
-
const txHash =
|
|
788
|
-
const sigCount =
|
|
789
|
-
const requiredSigners =
|
|
715
|
+
const txHash = (0, _txDialog.getTxBodyHash)(currentTx);
|
|
716
|
+
const sigCount = (0, _txDialog.countSignatures)(currentTx);
|
|
717
|
+
const requiredSigners = (0, _txDialog.getRequiredSigners)(currentTx);
|
|
790
718
|
console.log("");
|
|
791
|
-
console.log(`Transaction: ${
|
|
719
|
+
console.log(`Transaction: ${(0, _txDialog.formatHash)(txHash)}`);
|
|
792
720
|
if (requiredSigners.length > 0) {
|
|
793
721
|
console.log(`Signatures: ${sigCount} of ${requiredSigners.length} required`);
|
|
794
722
|
console.log("Required signers:");
|
|
795
723
|
for (const signer of requiredSigners) {
|
|
796
|
-
console.log(` - ${
|
|
724
|
+
console.log(` - ${(0, _txDialog.formatHash)(signer)}`);
|
|
797
725
|
}
|
|
798
726
|
} else {
|
|
799
727
|
console.log(`Signatures: ${sigCount}`);
|
|
@@ -843,11 +771,25 @@ class Sprinkle {
|
|
|
843
771
|
name: "Cancel",
|
|
844
772
|
value: "cancel"
|
|
845
773
|
});
|
|
846
|
-
const selection = await (0, _prompts.
|
|
774
|
+
const selection = await (0, _prompts.selectCancellable)({
|
|
847
775
|
message: "Select an option:",
|
|
848
776
|
choices
|
|
849
777
|
});
|
|
850
778
|
|
|
779
|
+
// Handle escape/cancel as cancel action
|
|
780
|
+
if (selection === null) {
|
|
781
|
+
if (hasSignedThisSession) {
|
|
782
|
+
return {
|
|
783
|
+
action: "signed",
|
|
784
|
+
tx: currentTx
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
return {
|
|
788
|
+
action: "cancelled",
|
|
789
|
+
tx: currentTx
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
|
|
851
793
|
// Handle selection
|
|
852
794
|
if (selection === "sign") {
|
|
853
795
|
if (opts?.beforeSign) {
|
|
@@ -913,7 +855,7 @@ class Sprinkle {
|
|
|
913
855
|
} else {
|
|
914
856
|
const signedTx = await blaze.signTransaction(currentTx);
|
|
915
857
|
// Merge signatures from signed tx into current tx
|
|
916
|
-
const added =
|
|
858
|
+
const added = (0, _txDialog.mergeSignatures)(currentTx, signedTx);
|
|
917
859
|
if (added > 0) {
|
|
918
860
|
console.log(`Added ${added} signature(s).`);
|
|
919
861
|
hasSignedThisSession = true;
|
|
@@ -945,10 +887,10 @@ class Sprinkle {
|
|
|
945
887
|
continue;
|
|
946
888
|
}
|
|
947
889
|
if (selection === "import") {
|
|
948
|
-
const cborInput = await (0, _prompts.
|
|
890
|
+
const cborInput = await (0, _prompts.inputCancellable)({
|
|
949
891
|
message: "Paste transaction CBOR (hex):"
|
|
950
892
|
});
|
|
951
|
-
if (
|
|
893
|
+
if (cborInput === null || cborInput.trim() === "") {
|
|
952
894
|
console.log("No CBOR provided.");
|
|
953
895
|
continue;
|
|
954
896
|
}
|
|
@@ -956,21 +898,21 @@ class Sprinkle {
|
|
|
956
898
|
const importedTx = _sdk.Core.Transaction.fromCbor((0, _core.TxCBOR)(cborInput.trim()));
|
|
957
899
|
|
|
958
900
|
// Validate body hash matches
|
|
959
|
-
const currentHash =
|
|
960
|
-
const importedHash =
|
|
901
|
+
const currentHash = (0, _txDialog.getTxBodyHash)(currentTx);
|
|
902
|
+
const importedHash = (0, _txDialog.getTxBodyHash)(importedTx);
|
|
961
903
|
if (currentHash !== importedHash) {
|
|
962
|
-
const proceed = await (0, _prompts.
|
|
963
|
-
message: `Warning: Imported transaction has different body hash.\nCurrent: ${
|
|
904
|
+
const proceed = await (0, _prompts.confirmCancellable)({
|
|
905
|
+
message: `Warning: Imported transaction has different body hash.\nCurrent: ${(0, _txDialog.formatHash)(currentHash)}\nImported: ${(0, _txDialog.formatHash)(importedHash)}\nProceed anyway?`,
|
|
964
906
|
default: false
|
|
965
907
|
});
|
|
966
|
-
if (!proceed) {
|
|
908
|
+
if (proceed === null || !proceed) {
|
|
967
909
|
console.log("Import cancelled.");
|
|
968
910
|
continue;
|
|
969
911
|
}
|
|
970
912
|
}
|
|
971
913
|
|
|
972
914
|
// Merge signatures
|
|
973
|
-
const added =
|
|
915
|
+
const added = (0, _txDialog.mergeSignatures)(currentTx, importedTx);
|
|
974
916
|
const sourceVkeys = importedTx.witnessSet().vkeys();
|
|
975
917
|
const sourceCount = sourceVkeys ? sourceVkeys.size() : 0;
|
|
976
918
|
const skipped = sourceCount - added;
|
|
@@ -989,13 +931,13 @@ class Sprinkle {
|
|
|
989
931
|
continue;
|
|
990
932
|
}
|
|
991
933
|
if (selection === "submit") {
|
|
992
|
-
const sigCount =
|
|
934
|
+
const sigCount = (0, _txDialog.countSignatures)(currentTx);
|
|
993
935
|
if (sigCount === 0) {
|
|
994
|
-
const proceed = await (0, _prompts.
|
|
936
|
+
const proceed = await (0, _prompts.confirmCancellable)({
|
|
995
937
|
message: "Warning: Transaction has no signatures. Submit anyway?",
|
|
996
938
|
default: false
|
|
997
939
|
});
|
|
998
|
-
if (!proceed) {
|
|
940
|
+
if (proceed === null || !proceed) {
|
|
999
941
|
continue;
|
|
1000
942
|
}
|
|
1001
943
|
}
|
|
@@ -1031,7 +973,7 @@ class Sprinkle {
|
|
|
1031
973
|
return this._editStruct(type, ["root"], current);
|
|
1032
974
|
}
|
|
1033
975
|
async _editStruct(type, path, current) {
|
|
1034
|
-
if (isObject(type)) {
|
|
976
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1035
977
|
const obj = {};
|
|
1036
978
|
const fields = type["properties"];
|
|
1037
979
|
const menuItems = [];
|
|
@@ -1041,7 +983,7 @@ class Sprinkle {
|
|
|
1041
983
|
obj[field] = currentRecord[field];
|
|
1042
984
|
}
|
|
1043
985
|
const menuTitle = Sprinkle.ExtractMessage(fieldType, `Edit ${field} at ${path.join(".")}`);
|
|
1044
|
-
if (isOptional(fieldType) && current && currentRecord[field] !== undefined) {
|
|
986
|
+
if ((0, _typeGuards.isOptional)(fieldType) && current && currentRecord[field] !== undefined) {
|
|
1045
987
|
menuItems.push({
|
|
1046
988
|
title: `Clear ${field}`,
|
|
1047
989
|
action: async sprinkle => {
|
|
@@ -1083,8 +1025,8 @@ class Sprinkle {
|
|
|
1083
1025
|
}
|
|
1084
1026
|
return this._fillInStruct(resolvedType, path, defs, def);
|
|
1085
1027
|
}
|
|
1086
|
-
if (isOptional(type)) {
|
|
1087
|
-
const shouldSet = await (0, _prompts.
|
|
1028
|
+
if ((0, _typeGuards.isOptional)(type)) {
|
|
1029
|
+
const shouldSet = await (0, _prompts.selectCancellable)({
|
|
1088
1030
|
message: Sprinkle.ExtractMessage(type, `Set value for ${path.join(".")}?`),
|
|
1089
1031
|
choices: [{
|
|
1090
1032
|
name: "Yes",
|
|
@@ -1095,6 +1037,9 @@ class Sprinkle {
|
|
|
1095
1037
|
}],
|
|
1096
1038
|
default: def !== undefined
|
|
1097
1039
|
});
|
|
1040
|
+
if (shouldSet === null) {
|
|
1041
|
+
throw new _types.UserCancelledError();
|
|
1042
|
+
}
|
|
1098
1043
|
if (!shouldSet) {
|
|
1099
1044
|
return undefined;
|
|
1100
1045
|
}
|
|
@@ -1105,7 +1050,7 @@ class Sprinkle {
|
|
|
1105
1050
|
delete innerType[_typebox.OptionalKind];
|
|
1106
1051
|
return this._fillInStruct(innerType, path, defs, def);
|
|
1107
1052
|
}
|
|
1108
|
-
if (isUnion(type)) {
|
|
1053
|
+
if ((0, _typeGuards.isUnion)(type)) {
|
|
1109
1054
|
const choices = [];
|
|
1110
1055
|
const resolved = this.resolveType(type, path, defs);
|
|
1111
1056
|
for (const variant of resolved.anyOf) {
|
|
@@ -1114,17 +1059,21 @@ class Sprinkle {
|
|
|
1114
1059
|
value: variant
|
|
1115
1060
|
});
|
|
1116
1061
|
}
|
|
1117
|
-
const
|
|
1062
|
+
const selectionResult = await (0, _prompts.selectCancellable)({
|
|
1118
1063
|
message: Sprinkle.ExtractMessage(resolved, `Enter a choice for ${path.join(".")}`),
|
|
1119
1064
|
choices: choices,
|
|
1120
1065
|
default: def ? `${def}` : undefined
|
|
1121
1066
|
});
|
|
1067
|
+
if (selectionResult === null) {
|
|
1068
|
+
throw new _types.UserCancelledError();
|
|
1069
|
+
}
|
|
1070
|
+
const selection = selectionResult;
|
|
1122
1071
|
return this._fillInStruct(selection, path, defs);
|
|
1123
1072
|
}
|
|
1124
|
-
if (isString(type)) {
|
|
1073
|
+
if ((0, _typeGuards.isString)(type)) {
|
|
1125
1074
|
// Special handling for hot wallet private key - offer generation option
|
|
1126
1075
|
if (type.title === "Hot Wallet Private Key") {
|
|
1127
|
-
const choice = await (0, _prompts.
|
|
1076
|
+
const choice = await (0, _prompts.selectCancellable)({
|
|
1128
1077
|
message: "Hot wallet setup:",
|
|
1129
1078
|
choices: [{
|
|
1130
1079
|
name: "Enter existing private key",
|
|
@@ -1134,33 +1083,44 @@ class Sprinkle {
|
|
|
1134
1083
|
value: "generate"
|
|
1135
1084
|
}]
|
|
1136
1085
|
});
|
|
1086
|
+
if (choice === null) {
|
|
1087
|
+
throw new _types.UserCancelledError();
|
|
1088
|
+
}
|
|
1137
1089
|
if (choice === "generate") {
|
|
1138
1090
|
return Sprinkle.generateWalletFromMnemonic();
|
|
1139
1091
|
}
|
|
1140
1092
|
// Fall through to password prompt for "existing" choice
|
|
1141
|
-
const answer = await (0, _prompts.
|
|
1093
|
+
const answer = await (0, _prompts.passwordCancellable)({
|
|
1142
1094
|
message: "Enter your private key:"
|
|
1143
1095
|
});
|
|
1096
|
+
if (answer === null) {
|
|
1097
|
+
throw new _types.UserCancelledError();
|
|
1098
|
+
}
|
|
1144
1099
|
return answer;
|
|
1145
1100
|
}
|
|
1146
1101
|
const defaultString = def ? def : this.defaults["string"];
|
|
1147
1102
|
const message = Sprinkle.ExtractMessage(type, `Enter a string for ${path.join(".")}`);
|
|
1148
1103
|
let answer;
|
|
1149
|
-
if (isSensitive(type)) {
|
|
1150
|
-
answer = await (0, _prompts.
|
|
1104
|
+
if ((0, _typeGuards.isSensitive)(type)) {
|
|
1105
|
+
answer = await (0, _prompts.passwordCancellable)({
|
|
1151
1106
|
message
|
|
1152
1107
|
});
|
|
1153
1108
|
} else {
|
|
1154
|
-
answer = await (0, _prompts.
|
|
1109
|
+
answer = await (0, _prompts.inputCancellable)({
|
|
1155
1110
|
message,
|
|
1156
1111
|
default: defaultString
|
|
1157
1112
|
});
|
|
1158
|
-
|
|
1113
|
+
if (answer !== null) {
|
|
1114
|
+
this.defaults["string"] = answer;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
if (answer === null) {
|
|
1118
|
+
throw new _types.UserCancelledError();
|
|
1159
1119
|
}
|
|
1160
1120
|
return answer;
|
|
1161
1121
|
}
|
|
1162
|
-
if (isBigInt(type)) {
|
|
1163
|
-
const answer = await (0, _prompts.
|
|
1122
|
+
if ((0, _typeGuards.isBigInt)(type)) {
|
|
1123
|
+
const answer = await (0, _prompts.inputCancellable)({
|
|
1164
1124
|
message: Sprinkle.ExtractMessage(type, `Enter a bigint for ${path.join(".")}`),
|
|
1165
1125
|
default: def ? def.toString() : undefined,
|
|
1166
1126
|
validate: s => {
|
|
@@ -1172,12 +1132,15 @@ class Sprinkle {
|
|
|
1172
1132
|
}
|
|
1173
1133
|
}
|
|
1174
1134
|
});
|
|
1135
|
+
if (answer === null) {
|
|
1136
|
+
throw new _types.UserCancelledError();
|
|
1137
|
+
}
|
|
1175
1138
|
return BigInt(answer);
|
|
1176
1139
|
}
|
|
1177
|
-
if (isLiteral(type)) {
|
|
1140
|
+
if ((0, _typeGuards.isLiteral)(type)) {
|
|
1178
1141
|
return type.const;
|
|
1179
1142
|
}
|
|
1180
|
-
if (isObject(type)) {
|
|
1143
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1181
1144
|
const obj = {};
|
|
1182
1145
|
const fields = type["properties"];
|
|
1183
1146
|
for (const [field, fieldType] of Object.entries(fields)) {
|
|
@@ -1188,14 +1151,14 @@ class Sprinkle {
|
|
|
1188
1151
|
}
|
|
1189
1152
|
|
|
1190
1153
|
//TODO: support starting with default values for arrays and allow removal of items
|
|
1191
|
-
if (isArray(type)) {
|
|
1154
|
+
if ((0, _typeGuards.isArray)(type)) {
|
|
1192
1155
|
const arr = [];
|
|
1193
1156
|
const itemType = type.items;
|
|
1194
1157
|
let addMore = true;
|
|
1195
1158
|
while (addMore) {
|
|
1196
1159
|
const itemValue = await this._fillInStruct(itemType, path.concat([`[${arr.length}]`]), defs);
|
|
1197
1160
|
arr.push(itemValue);
|
|
1198
|
-
const continueAnswer = await (0, _prompts.
|
|
1161
|
+
const continueAnswer = await (0, _prompts.selectCancellable)({
|
|
1199
1162
|
message: `Add another item to ${path.join(".")}?`,
|
|
1200
1163
|
choices: [{
|
|
1201
1164
|
name: "Yes",
|
|
@@ -1205,11 +1168,14 @@ class Sprinkle {
|
|
|
1205
1168
|
value: false
|
|
1206
1169
|
}]
|
|
1207
1170
|
});
|
|
1171
|
+
if (continueAnswer === null) {
|
|
1172
|
+
throw new _types.UserCancelledError();
|
|
1173
|
+
}
|
|
1208
1174
|
addMore = continueAnswer;
|
|
1209
1175
|
}
|
|
1210
1176
|
return arr;
|
|
1211
1177
|
}
|
|
1212
|
-
if (isTuple(type)) {
|
|
1178
|
+
if ((0, _typeGuards.isTuple)(type)) {
|
|
1213
1179
|
const items = type.items ?? [];
|
|
1214
1180
|
const result = [];
|
|
1215
1181
|
for (let i = 0; i < items.length; i++) {
|
|
@@ -1222,7 +1188,7 @@ class Sprinkle {
|
|
|
1222
1188
|
throw new Error(`Unable to fill in struct for type at path ${path.join(".")}`);
|
|
1223
1189
|
}
|
|
1224
1190
|
resolveType(type, path, defs) {
|
|
1225
|
-
if (isRef(type) || isThis(type) || isImport(type)) {
|
|
1191
|
+
if ((0, _typeGuards.isRef)(type) || (0, _typeGuards.isThis)(type) || (0, _typeGuards.isImport)(type)) {
|
|
1226
1192
|
defs = {
|
|
1227
1193
|
...defs,
|
|
1228
1194
|
...type.$defs
|
|
@@ -1242,10 +1208,10 @@ class Sprinkle {
|
|
|
1242
1208
|
if ("description" in type) {
|
|
1243
1209
|
return type.description;
|
|
1244
1210
|
}
|
|
1245
|
-
if (isLiteral(type)) {
|
|
1211
|
+
if ((0, _typeGuards.isLiteral)(type)) {
|
|
1246
1212
|
return `${type.const}`;
|
|
1247
1213
|
}
|
|
1248
|
-
if (isObject(type)) {
|
|
1214
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1249
1215
|
const fields = type["properties"];
|
|
1250
1216
|
if ("type" in fields) {
|
|
1251
1217
|
return Sprinkle.ExtractMessage(fields["type"], def);
|