@sundaeswap/sprinkles 0.4.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__/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 +307 -362
- 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__/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 +161 -347
- 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 +11 -177
- 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__/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 +254 -496
- 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);
|
|
@@ -232,32 +293,42 @@ class Sprinkle {
|
|
|
232
293
|
meta: this.profileMeta,
|
|
233
294
|
settings: settingsToSave,
|
|
234
295
|
defaults: this.defaults
|
|
235
|
-
},
|
|
296
|
+
}, _encryption.bigIntReplacer, 2);
|
|
236
297
|
fs.writeFileSync(filePath, jsonContent, "utf-8");
|
|
237
298
|
}
|
|
238
299
|
async promptProfileMeta(defaultName, defaultDescription) {
|
|
239
|
-
const name = await (0, _prompts.
|
|
300
|
+
const name = await (0, _prompts.inputCancellable)({
|
|
240
301
|
message: "Profile name:",
|
|
241
302
|
default: defaultName,
|
|
242
303
|
validate: v => v.trim().length > 0 ? true : "Name cannot be empty"
|
|
243
304
|
});
|
|
244
|
-
|
|
305
|
+
if (name === null) return null; // User cancelled
|
|
306
|
+
const description = await (0, _prompts.inputCancellable)({
|
|
245
307
|
message: "Profile description (optional):",
|
|
246
308
|
default: defaultDescription ?? ""
|
|
247
309
|
});
|
|
310
|
+
if (description === null) return null; // User cancelled
|
|
248
311
|
return {
|
|
249
312
|
name,
|
|
250
313
|
description: description || undefined
|
|
251
314
|
};
|
|
252
315
|
}
|
|
253
316
|
async createProfile() {
|
|
317
|
+
const result = await this.promptProfileMeta();
|
|
318
|
+
if (result === null) return; // User cancelled
|
|
254
319
|
const {
|
|
255
320
|
name,
|
|
256
321
|
description
|
|
257
|
-
} =
|
|
322
|
+
} = result;
|
|
258
323
|
const profilesDir = Sprinkle.profilesDir(this.storagePath);
|
|
259
324
|
const id = Sprinkle.findAvailableId(profilesDir, Sprinkle.sanitizeProfileId(name));
|
|
260
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;
|
|
261
332
|
this.profileId = id;
|
|
262
333
|
this.profileMeta = {
|
|
263
334
|
name,
|
|
@@ -266,7 +337,19 @@ class Sprinkle {
|
|
|
266
337
|
updatedAt: now
|
|
267
338
|
};
|
|
268
339
|
this.defaults = {};
|
|
269
|
-
|
|
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
|
+
}
|
|
270
353
|
this.saveProfile();
|
|
271
354
|
fs.writeFileSync(Sprinkle.activeProfilePath(this.storagePath), id, "utf-8");
|
|
272
355
|
}
|
|
@@ -291,7 +374,7 @@ class Sprinkle {
|
|
|
291
374
|
fs.mkdirSync(profilesDir, {
|
|
292
375
|
recursive: true
|
|
293
376
|
});
|
|
294
|
-
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");
|
|
295
378
|
fs.writeFileSync(Sprinkle.activeProfilePath(this.storagePath), "default", "utf-8");
|
|
296
379
|
// Backup legacy file
|
|
297
380
|
fs.renameSync(legacyPath, `${legacyPath}.bak`);
|
|
@@ -328,23 +411,26 @@ class Sprinkle {
|
|
|
328
411
|
}
|
|
329
412
|
async selectProfile(profiles) {
|
|
330
413
|
const available = profiles ?? this.scanProfiles();
|
|
331
|
-
const selection = await (0, _prompts.
|
|
414
|
+
const selection = await (0, _prompts.selectCancellable)({
|
|
332
415
|
message: "Select a profile:",
|
|
333
416
|
choices: available.map(p => ({
|
|
334
417
|
name: p.meta.description ? `${p.meta.name} - ${p.meta.description}` : p.meta.name,
|
|
335
418
|
value: p.id
|
|
336
419
|
}))
|
|
337
420
|
});
|
|
421
|
+
if (selection === null) return; // User cancelled
|
|
338
422
|
await this.loadProfile(selection);
|
|
339
423
|
}
|
|
340
424
|
|
|
341
425
|
// --- Profile management (CRUD) ---
|
|
342
426
|
|
|
343
427
|
async duplicateProfile() {
|
|
428
|
+
const result = await this.promptProfileMeta(`${this.profileMeta.name} (copy)`, this.profileMeta.description);
|
|
429
|
+
if (result === null) return; // User cancelled
|
|
344
430
|
const {
|
|
345
431
|
name,
|
|
346
432
|
description
|
|
347
|
-
} =
|
|
433
|
+
} = result;
|
|
348
434
|
const profilesDir = Sprinkle.profilesDir(this.storagePath);
|
|
349
435
|
const id = Sprinkle.findAvailableId(profilesDir, Sprinkle.sanitizeProfileId(name));
|
|
350
436
|
const now = new Date().toISOString();
|
|
@@ -359,15 +445,17 @@ class Sprinkle {
|
|
|
359
445
|
},
|
|
360
446
|
settings: settingsToSave,
|
|
361
447
|
defaults: this.defaults
|
|
362
|
-
},
|
|
448
|
+
}, _encryption.bigIntReplacer, 2);
|
|
363
449
|
fs.writeFileSync(path.join(profilesDir, `${id}.json`), jsonContent, "utf-8");
|
|
364
450
|
console.log(`Profile "${name}" created as a copy.`);
|
|
365
451
|
}
|
|
366
452
|
async renameProfile() {
|
|
453
|
+
const result = await this.promptProfileMeta(this.profileMeta.name, this.profileMeta.description);
|
|
454
|
+
if (result === null) return; // User cancelled
|
|
367
455
|
const {
|
|
368
456
|
name,
|
|
369
457
|
description
|
|
370
|
-
} =
|
|
458
|
+
} = result;
|
|
371
459
|
const newId = Sprinkle.sanitizeProfileId(name);
|
|
372
460
|
const oldId = this.profileId;
|
|
373
461
|
this.profileMeta.name = name;
|
|
@@ -395,25 +483,26 @@ class Sprinkle {
|
|
|
395
483
|
console.log("Cannot delete the only profile.");
|
|
396
484
|
return;
|
|
397
485
|
}
|
|
398
|
-
const toDelete = await (0, _prompts.
|
|
486
|
+
const toDelete = await (0, _prompts.selectCancellable)({
|
|
399
487
|
message: "Select a profile to delete:",
|
|
400
|
-
choices:
|
|
488
|
+
choices: others.map(p => ({
|
|
401
489
|
name: p.meta.description ? `${p.meta.name} - ${p.meta.description}` : p.meta.name,
|
|
402
490
|
value: p.id
|
|
403
|
-
}))
|
|
404
|
-
name: "Cancel",
|
|
405
|
-
value: "__cancel__"
|
|
406
|
-
}]
|
|
491
|
+
}))
|
|
407
492
|
});
|
|
408
|
-
if (toDelete ===
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
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.`,
|
|
412
499
|
default: false
|
|
413
500
|
});
|
|
501
|
+
if (confirmed === null) return; // User cancelled
|
|
502
|
+
|
|
414
503
|
if (confirmed) {
|
|
415
|
-
fs.unlinkSync(Sprinkle.profilePath(this.storagePath,
|
|
416
|
-
console.log(`Profile "${profileToDelete?.meta.name ??
|
|
504
|
+
fs.unlinkSync(Sprinkle.profilePath(this.storagePath, profileId));
|
|
505
|
+
console.log(`Profile "${profileToDelete?.meta.name ?? profileId}" deleted.`);
|
|
417
506
|
}
|
|
418
507
|
}
|
|
419
508
|
|
|
@@ -454,14 +543,24 @@ class Sprinkle {
|
|
|
454
543
|
value: -1
|
|
455
544
|
});
|
|
456
545
|
}
|
|
457
|
-
const
|
|
546
|
+
const selectionResult = await (0, _prompts.selectCancellable)({
|
|
458
547
|
message: "Select an option:",
|
|
459
548
|
choices: choices
|
|
460
549
|
});
|
|
550
|
+
// Handle escape (null) as Back
|
|
551
|
+
if (selectionResult === null) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const selection = selectionResult;
|
|
461
555
|
if (selection === -5) {
|
|
462
556
|
const settingsMenu = {
|
|
463
557
|
title: "Settings & Profiles",
|
|
464
558
|
items: [{
|
|
559
|
+
title: "View settings",
|
|
560
|
+
action: async () => {
|
|
561
|
+
console.log(JSON.stringify(this.getDisplaySettings(), _encryption.bigIntReplacer, 2));
|
|
562
|
+
}
|
|
563
|
+
}, {
|
|
465
564
|
title: "Edit settings",
|
|
466
565
|
action: async () => {
|
|
467
566
|
this.settings = await this.EditStruct(this.type, this.settings);
|
|
@@ -529,40 +628,13 @@ class Sprinkle {
|
|
|
529
628
|
return sprinkle;
|
|
530
629
|
}
|
|
531
630
|
static async GetProvider(network, settings) {
|
|
532
|
-
|
|
533
|
-
case "blockfrost":
|
|
534
|
-
return new _query.Blockfrost({
|
|
535
|
-
network: `cardano-${network}`,
|
|
536
|
-
projectId: settings.projectId
|
|
537
|
-
});
|
|
538
|
-
case "maestro":
|
|
539
|
-
// Dynamic import - Maestro may or may not be exported depending on @blaze-cardano/query version
|
|
540
|
-
const queryModule = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/query")));
|
|
541
|
-
if (!queryModule.Maestro) {
|
|
542
|
-
throw new Error("Maestro is not available in the installed version of @blaze-cardano/query. Please install a version that includes Maestro support.");
|
|
543
|
-
}
|
|
544
|
-
return new queryModule.Maestro({
|
|
545
|
-
network: network,
|
|
546
|
-
apiKey: settings.apiKey
|
|
547
|
-
});
|
|
548
|
-
default:
|
|
549
|
-
throw new Error("Invalid provider type");
|
|
550
|
-
}
|
|
631
|
+
return (0, _wallet.GetProvider)(network, settings);
|
|
551
632
|
}
|
|
552
633
|
static async GetWallet(settings, provider) {
|
|
553
|
-
|
|
554
|
-
case "hot":
|
|
555
|
-
return _sdk.HotWallet.fromMasterkey(_sdk.Core.Bip32PrivateKeyHex(settings.privateKey), provider, provider.network);
|
|
556
|
-
case "cold":
|
|
557
|
-
return new _sdk.ColdWallet(_sdk.Core.Address.fromBech32(settings.address), provider.network, provider);
|
|
558
|
-
default:
|
|
559
|
-
throw new Error("Invalid wallet type");
|
|
560
|
-
}
|
|
634
|
+
return (0, _wallet.GetWallet)(settings, provider);
|
|
561
635
|
}
|
|
562
636
|
static async GetBlaze(network, providerSettings, walletSettings) {
|
|
563
|
-
|
|
564
|
-
const wallet = await Sprinkle.GetWallet(walletSettings, provider);
|
|
565
|
-
return _sdk.Blaze.from(provider, wallet);
|
|
637
|
+
return (0, _wallet.GetBlaze)(network, providerSettings, walletSettings);
|
|
566
638
|
}
|
|
567
639
|
|
|
568
640
|
/**
|
|
@@ -571,30 +643,10 @@ class Sprinkle {
|
|
|
571
643
|
* @returns The Bip32PrivateKey hex string for storage
|
|
572
644
|
*/
|
|
573
645
|
static async generateWalletFromMnemonic() {
|
|
574
|
-
|
|
575
|
-
const words = mnemonic.split(" ");
|
|
576
|
-
console.log("\n=== NEW WALLET GENERATED ===\n");
|
|
577
|
-
console.log("IMPORTANT: Save these 24 words in a secure location.");
|
|
578
|
-
console.log("This is the ONLY way to recover your wallet.\n");
|
|
579
|
-
|
|
580
|
-
// Display in 4 columns
|
|
581
|
-
for (let i = 0; i < 6; i++) {
|
|
582
|
-
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]}`);
|
|
583
|
-
}
|
|
584
|
-
console.log("");
|
|
585
|
-
const confirmed = await (0, _prompts.confirm)({
|
|
586
|
-
message: "Have you saved your recovery phrase?",
|
|
587
|
-
default: false
|
|
588
|
-
});
|
|
589
|
-
if (!confirmed) {
|
|
590
|
-
throw new Error("Wallet generation cancelled - recovery phrase not saved");
|
|
591
|
-
}
|
|
592
|
-
const entropy = _sdk.Core.mnemonicToEntropy(mnemonic, _core.wordlist);
|
|
593
|
-
const masterKey = _sdk.Core.Bip32PrivateKey.fromBip39Entropy(Buffer.from(entropy), "");
|
|
594
|
-
return masterKey.hex();
|
|
646
|
+
return (0, _wallet.generateWalletFromMnemonic)();
|
|
595
647
|
}
|
|
596
648
|
static async SearchSelect(opts) {
|
|
597
|
-
return (0, _prompts.
|
|
649
|
+
return (0, _prompts.searchCancellable)(opts);
|
|
598
650
|
}
|
|
599
651
|
static SettingsPath(storagePath) {
|
|
600
652
|
return `${storagePath}${path.sep}settings.json`;
|
|
@@ -618,166 +670,21 @@ class Sprinkle {
|
|
|
618
670
|
}
|
|
619
671
|
}
|
|
620
672
|
static bigIntReviver(key, value) {
|
|
621
|
-
|
|
622
|
-
return BigInt(value.slice(0, -1));
|
|
623
|
-
}
|
|
624
|
-
return value;
|
|
625
|
-
}
|
|
626
|
-
static bigIntReplacer(_key, value) {
|
|
627
|
-
return typeof value === "bigint" ? `${value.toString()}n` : value;
|
|
628
|
-
}
|
|
629
|
-
static collectSensitivePaths(type, prefix = "") {
|
|
630
|
-
const paths = [];
|
|
631
|
-
if (isObject(type)) {
|
|
632
|
-
const fields = type["properties"];
|
|
633
|
-
for (const [field, fieldType] of Object.entries(fields)) {
|
|
634
|
-
const fieldPath = prefix ? `${prefix}.${field}` : field;
|
|
635
|
-
if (isSensitive(fieldType)) {
|
|
636
|
-
paths.push(fieldPath);
|
|
637
|
-
}
|
|
638
|
-
paths.push(...Sprinkle.collectSensitivePaths(fieldType, fieldPath));
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
if (isUnion(type)) {
|
|
642
|
-
for (const variant of type.anyOf) {
|
|
643
|
-
paths.push(...Sprinkle.collectSensitivePaths(variant, prefix));
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
return paths;
|
|
647
|
-
}
|
|
648
|
-
static getNestedValue(obj, path) {
|
|
649
|
-
return path.split(".").reduce((o, k) => o?.[k], obj);
|
|
650
|
-
}
|
|
651
|
-
static setNestedValue(obj, path, value) {
|
|
652
|
-
const keys = path.split(".");
|
|
653
|
-
const last = keys.pop();
|
|
654
|
-
const parent = keys.reduce((o, k) => o?.[k], obj);
|
|
655
|
-
if (parent && typeof parent === "object") {
|
|
656
|
-
parent[last] = value;
|
|
657
|
-
}
|
|
673
|
+
return (0, _encryption.bigIntReviver)(key, value);
|
|
658
674
|
}
|
|
659
675
|
encryptSettings(settings) {
|
|
660
676
|
if (!this.options.encryption) return settings;
|
|
661
|
-
|
|
662
|
-
const sensitivePaths = Sprinkle.collectSensitivePaths(this.type);
|
|
663
|
-
for (const p of sensitivePaths) {
|
|
664
|
-
const value = Sprinkle.getNestedValue(clone, p);
|
|
665
|
-
if (typeof value === "string" && value.length > 0) {
|
|
666
|
-
Sprinkle.setNestedValue(clone, p, this.options.encryption.encrypt(value));
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
return clone;
|
|
677
|
+
return (0, _encryption.encryptSensitiveFields)(settings, this.type, this.options.encryption);
|
|
670
678
|
}
|
|
671
679
|
async decryptSettings(settings) {
|
|
672
680
|
if (!this.options.encryption) return settings;
|
|
673
|
-
|
|
674
|
-
const sensitivePaths = Sprinkle.collectSensitivePaths(this.type);
|
|
675
|
-
for (const p of sensitivePaths) {
|
|
676
|
-
const value = Sprinkle.getNestedValue(clone, p);
|
|
677
|
-
if (typeof value === "string" && value.length > 0) {
|
|
678
|
-
Sprinkle.setNestedValue(clone, p, await this.options.encryption.decrypt(value));
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
return clone;
|
|
681
|
+
return (0, _encryption.decryptSensitiveFields)(settings, this.type, this.options.encryption);
|
|
682
682
|
}
|
|
683
683
|
saveSettings() {
|
|
684
684
|
this.saveProfile();
|
|
685
685
|
}
|
|
686
686
|
getDisplaySettings() {
|
|
687
|
-
|
|
688
|
-
const sensitivePaths = Sprinkle.collectSensitivePaths(this.type);
|
|
689
|
-
for (const p of sensitivePaths) {
|
|
690
|
-
const value = Sprinkle.getNestedValue(clone, p);
|
|
691
|
-
if (typeof value === "string" && value.length > 0) {
|
|
692
|
-
Sprinkle.setNestedValue(clone, p, "********");
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
return clone;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// --- TxDialog Helpers ---
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* Get the payment key hash from a HotWallet's first address
|
|
702
|
-
*/
|
|
703
|
-
async getWalletPaymentKeyHash(wallet) {
|
|
704
|
-
try {
|
|
705
|
-
const addresses = await wallet.getUsedAddresses();
|
|
706
|
-
const address = addresses[0];
|
|
707
|
-
if (!address) return null;
|
|
708
|
-
const paymentCredential = address.asBase()?.getPaymentCredential();
|
|
709
|
-
return paymentCredential?.hash?.toString() ?? null;
|
|
710
|
-
} catch {
|
|
711
|
-
return null;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* Count the number of vkey signatures in a transaction's witness set
|
|
717
|
-
*/
|
|
718
|
-
countSignatures(tx) {
|
|
719
|
-
const vkeys = tx.witnessSet().vkeys();
|
|
720
|
-
return vkeys ? vkeys.size() : 0;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
/**
|
|
724
|
-
* Check if a specific public key has already signed the transaction
|
|
725
|
-
* Compares by vkey (public key bytes)
|
|
726
|
-
*/
|
|
727
|
-
hasVkeySigned(tx, vkeyHex) {
|
|
728
|
-
const vkeys = tx.witnessSet().vkeys();
|
|
729
|
-
if (!vkeys) return false;
|
|
730
|
-
const vkeyArray = vkeys.toCore();
|
|
731
|
-
return vkeyArray.some(([vkey]) => vkey === vkeyHex);
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
/**
|
|
735
|
-
* Get the list of required signer key hashes from the transaction body
|
|
736
|
-
*/
|
|
737
|
-
getRequiredSigners(tx) {
|
|
738
|
-
const requiredSigners = tx.body().requiredSigners();
|
|
739
|
-
if (!requiredSigners) return [];
|
|
740
|
-
return Array.from(requiredSigners.values()).map(s => s.toString());
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
/**
|
|
744
|
-
* Compute the transaction body hash for display
|
|
745
|
-
*/
|
|
746
|
-
getTxBodyHash(tx) {
|
|
747
|
-
const bodyCbor = tx.body().toCbor();
|
|
748
|
-
return (0, _core.blake2b_256)(bodyCbor);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
* Format a hash for display: first 8 chars + ... + last 8 chars
|
|
753
|
-
*/
|
|
754
|
-
formatHash(hash) {
|
|
755
|
-
if (hash.length <= 20) return hash;
|
|
756
|
-
return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* Merge signatures from source transaction into target transaction.
|
|
761
|
-
* Prevents duplicate signatures by comparing vkey (public key).
|
|
762
|
-
* Returns the count of newly added signatures.
|
|
763
|
-
*/
|
|
764
|
-
mergeSignatures(target, source) {
|
|
765
|
-
const targetWs = target.witnessSet();
|
|
766
|
-
const sourceWs = source.witnessSet();
|
|
767
|
-
const targetVkeys = targetWs.vkeys()?.toCore() ?? [];
|
|
768
|
-
const sourceVkeys = sourceWs.vkeys()?.toCore() ?? [];
|
|
769
|
-
|
|
770
|
-
// Find vkeys in source that aren't in target (by comparing public key)
|
|
771
|
-
const existingPubKeys = new Set(targetVkeys.map(([vkey]) => vkey));
|
|
772
|
-
const newVkeys = sourceVkeys.filter(([vkey]) => !existingPubKeys.has(vkey));
|
|
773
|
-
if (newVkeys.length === 0) {
|
|
774
|
-
return 0;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
// Merge the new vkeys into target
|
|
778
|
-
targetWs.setVkeys(_core.CborSet.fromCore([...targetVkeys, ...newVkeys], _core.VkeyWitness.fromCore));
|
|
779
|
-
target.setWitnessSet(targetWs);
|
|
780
|
-
return newVkeys.length;
|
|
687
|
+
return (0, _encryption.maskSensitiveFields)(this.settings, this.type);
|
|
781
688
|
}
|
|
782
689
|
async TxDialog(blaze, tx, opts) {
|
|
783
690
|
let currentTx = tx;
|
|
@@ -805,16 +712,16 @@ class Sprinkle {
|
|
|
805
712
|
}
|
|
806
713
|
while (true) {
|
|
807
714
|
// Display transaction status
|
|
808
|
-
const txHash =
|
|
809
|
-
const sigCount =
|
|
810
|
-
const requiredSigners =
|
|
715
|
+
const txHash = (0, _txDialog.getTxBodyHash)(currentTx);
|
|
716
|
+
const sigCount = (0, _txDialog.countSignatures)(currentTx);
|
|
717
|
+
const requiredSigners = (0, _txDialog.getRequiredSigners)(currentTx);
|
|
811
718
|
console.log("");
|
|
812
|
-
console.log(`Transaction: ${
|
|
719
|
+
console.log(`Transaction: ${(0, _txDialog.formatHash)(txHash)}`);
|
|
813
720
|
if (requiredSigners.length > 0) {
|
|
814
721
|
console.log(`Signatures: ${sigCount} of ${requiredSigners.length} required`);
|
|
815
722
|
console.log("Required signers:");
|
|
816
723
|
for (const signer of requiredSigners) {
|
|
817
|
-
console.log(` - ${
|
|
724
|
+
console.log(` - ${(0, _txDialog.formatHash)(signer)}`);
|
|
818
725
|
}
|
|
819
726
|
} else {
|
|
820
727
|
console.log(`Signatures: ${sigCount}`);
|
|
@@ -864,11 +771,25 @@ class Sprinkle {
|
|
|
864
771
|
name: "Cancel",
|
|
865
772
|
value: "cancel"
|
|
866
773
|
});
|
|
867
|
-
const selection = await (0, _prompts.
|
|
774
|
+
const selection = await (0, _prompts.selectCancellable)({
|
|
868
775
|
message: "Select an option:",
|
|
869
776
|
choices
|
|
870
777
|
});
|
|
871
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
|
+
|
|
872
793
|
// Handle selection
|
|
873
794
|
if (selection === "sign") {
|
|
874
795
|
if (opts?.beforeSign) {
|
|
@@ -934,7 +855,7 @@ class Sprinkle {
|
|
|
934
855
|
} else {
|
|
935
856
|
const signedTx = await blaze.signTransaction(currentTx);
|
|
936
857
|
// Merge signatures from signed tx into current tx
|
|
937
|
-
const added =
|
|
858
|
+
const added = (0, _txDialog.mergeSignatures)(currentTx, signedTx);
|
|
938
859
|
if (added > 0) {
|
|
939
860
|
console.log(`Added ${added} signature(s).`);
|
|
940
861
|
hasSignedThisSession = true;
|
|
@@ -966,10 +887,10 @@ class Sprinkle {
|
|
|
966
887
|
continue;
|
|
967
888
|
}
|
|
968
889
|
if (selection === "import") {
|
|
969
|
-
const cborInput = await (0, _prompts.
|
|
890
|
+
const cborInput = await (0, _prompts.inputCancellable)({
|
|
970
891
|
message: "Paste transaction CBOR (hex):"
|
|
971
892
|
});
|
|
972
|
-
if (
|
|
893
|
+
if (cborInput === null || cborInput.trim() === "") {
|
|
973
894
|
console.log("No CBOR provided.");
|
|
974
895
|
continue;
|
|
975
896
|
}
|
|
@@ -977,21 +898,21 @@ class Sprinkle {
|
|
|
977
898
|
const importedTx = _sdk.Core.Transaction.fromCbor((0, _core.TxCBOR)(cborInput.trim()));
|
|
978
899
|
|
|
979
900
|
// Validate body hash matches
|
|
980
|
-
const currentHash =
|
|
981
|
-
const importedHash =
|
|
901
|
+
const currentHash = (0, _txDialog.getTxBodyHash)(currentTx);
|
|
902
|
+
const importedHash = (0, _txDialog.getTxBodyHash)(importedTx);
|
|
982
903
|
if (currentHash !== importedHash) {
|
|
983
|
-
const proceed = await (0, _prompts.
|
|
984
|
-
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?`,
|
|
985
906
|
default: false
|
|
986
907
|
});
|
|
987
|
-
if (!proceed) {
|
|
908
|
+
if (proceed === null || !proceed) {
|
|
988
909
|
console.log("Import cancelled.");
|
|
989
910
|
continue;
|
|
990
911
|
}
|
|
991
912
|
}
|
|
992
913
|
|
|
993
914
|
// Merge signatures
|
|
994
|
-
const added =
|
|
915
|
+
const added = (0, _txDialog.mergeSignatures)(currentTx, importedTx);
|
|
995
916
|
const sourceVkeys = importedTx.witnessSet().vkeys();
|
|
996
917
|
const sourceCount = sourceVkeys ? sourceVkeys.size() : 0;
|
|
997
918
|
const skipped = sourceCount - added;
|
|
@@ -1010,13 +931,13 @@ class Sprinkle {
|
|
|
1010
931
|
continue;
|
|
1011
932
|
}
|
|
1012
933
|
if (selection === "submit") {
|
|
1013
|
-
const sigCount =
|
|
934
|
+
const sigCount = (0, _txDialog.countSignatures)(currentTx);
|
|
1014
935
|
if (sigCount === 0) {
|
|
1015
|
-
const proceed = await (0, _prompts.
|
|
936
|
+
const proceed = await (0, _prompts.confirmCancellable)({
|
|
1016
937
|
message: "Warning: Transaction has no signatures. Submit anyway?",
|
|
1017
938
|
default: false
|
|
1018
939
|
});
|
|
1019
|
-
if (!proceed) {
|
|
940
|
+
if (proceed === null || !proceed) {
|
|
1020
941
|
continue;
|
|
1021
942
|
}
|
|
1022
943
|
}
|
|
@@ -1052,7 +973,7 @@ class Sprinkle {
|
|
|
1052
973
|
return this._editStruct(type, ["root"], current);
|
|
1053
974
|
}
|
|
1054
975
|
async _editStruct(type, path, current) {
|
|
1055
|
-
if (isObject(type)) {
|
|
976
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1056
977
|
const obj = {};
|
|
1057
978
|
const fields = type["properties"];
|
|
1058
979
|
const menuItems = [];
|
|
@@ -1062,7 +983,7 @@ class Sprinkle {
|
|
|
1062
983
|
obj[field] = currentRecord[field];
|
|
1063
984
|
}
|
|
1064
985
|
const menuTitle = Sprinkle.ExtractMessage(fieldType, `Edit ${field} at ${path.join(".")}`);
|
|
1065
|
-
if (isOptional(fieldType) && current && currentRecord[field] !== undefined) {
|
|
986
|
+
if ((0, _typeGuards.isOptional)(fieldType) && current && currentRecord[field] !== undefined) {
|
|
1066
987
|
menuItems.push({
|
|
1067
988
|
title: `Clear ${field}`,
|
|
1068
989
|
action: async sprinkle => {
|
|
@@ -1104,8 +1025,8 @@ class Sprinkle {
|
|
|
1104
1025
|
}
|
|
1105
1026
|
return this._fillInStruct(resolvedType, path, defs, def);
|
|
1106
1027
|
}
|
|
1107
|
-
if (isOptional(type)) {
|
|
1108
|
-
const shouldSet = await (0, _prompts.
|
|
1028
|
+
if ((0, _typeGuards.isOptional)(type)) {
|
|
1029
|
+
const shouldSet = await (0, _prompts.selectCancellable)({
|
|
1109
1030
|
message: Sprinkle.ExtractMessage(type, `Set value for ${path.join(".")}?`),
|
|
1110
1031
|
choices: [{
|
|
1111
1032
|
name: "Yes",
|
|
@@ -1116,6 +1037,9 @@ class Sprinkle {
|
|
|
1116
1037
|
}],
|
|
1117
1038
|
default: def !== undefined
|
|
1118
1039
|
});
|
|
1040
|
+
if (shouldSet === null) {
|
|
1041
|
+
throw new _types.UserCancelledError();
|
|
1042
|
+
}
|
|
1119
1043
|
if (!shouldSet) {
|
|
1120
1044
|
return undefined;
|
|
1121
1045
|
}
|
|
@@ -1126,7 +1050,7 @@ class Sprinkle {
|
|
|
1126
1050
|
delete innerType[_typebox.OptionalKind];
|
|
1127
1051
|
return this._fillInStruct(innerType, path, defs, def);
|
|
1128
1052
|
}
|
|
1129
|
-
if (isUnion(type)) {
|
|
1053
|
+
if ((0, _typeGuards.isUnion)(type)) {
|
|
1130
1054
|
const choices = [];
|
|
1131
1055
|
const resolved = this.resolveType(type, path, defs);
|
|
1132
1056
|
for (const variant of resolved.anyOf) {
|
|
@@ -1135,17 +1059,21 @@ class Sprinkle {
|
|
|
1135
1059
|
value: variant
|
|
1136
1060
|
});
|
|
1137
1061
|
}
|
|
1138
|
-
const
|
|
1062
|
+
const selectionResult = await (0, _prompts.selectCancellable)({
|
|
1139
1063
|
message: Sprinkle.ExtractMessage(resolved, `Enter a choice for ${path.join(".")}`),
|
|
1140
1064
|
choices: choices,
|
|
1141
1065
|
default: def ? `${def}` : undefined
|
|
1142
1066
|
});
|
|
1067
|
+
if (selectionResult === null) {
|
|
1068
|
+
throw new _types.UserCancelledError();
|
|
1069
|
+
}
|
|
1070
|
+
const selection = selectionResult;
|
|
1143
1071
|
return this._fillInStruct(selection, path, defs);
|
|
1144
1072
|
}
|
|
1145
|
-
if (isString(type)) {
|
|
1073
|
+
if ((0, _typeGuards.isString)(type)) {
|
|
1146
1074
|
// Special handling for hot wallet private key - offer generation option
|
|
1147
1075
|
if (type.title === "Hot Wallet Private Key") {
|
|
1148
|
-
const choice = await (0, _prompts.
|
|
1076
|
+
const choice = await (0, _prompts.selectCancellable)({
|
|
1149
1077
|
message: "Hot wallet setup:",
|
|
1150
1078
|
choices: [{
|
|
1151
1079
|
name: "Enter existing private key",
|
|
@@ -1155,33 +1083,44 @@ class Sprinkle {
|
|
|
1155
1083
|
value: "generate"
|
|
1156
1084
|
}]
|
|
1157
1085
|
});
|
|
1086
|
+
if (choice === null) {
|
|
1087
|
+
throw new _types.UserCancelledError();
|
|
1088
|
+
}
|
|
1158
1089
|
if (choice === "generate") {
|
|
1159
1090
|
return Sprinkle.generateWalletFromMnemonic();
|
|
1160
1091
|
}
|
|
1161
1092
|
// Fall through to password prompt for "existing" choice
|
|
1162
|
-
const answer = await (0, _prompts.
|
|
1093
|
+
const answer = await (0, _prompts.passwordCancellable)({
|
|
1163
1094
|
message: "Enter your private key:"
|
|
1164
1095
|
});
|
|
1096
|
+
if (answer === null) {
|
|
1097
|
+
throw new _types.UserCancelledError();
|
|
1098
|
+
}
|
|
1165
1099
|
return answer;
|
|
1166
1100
|
}
|
|
1167
1101
|
const defaultString = def ? def : this.defaults["string"];
|
|
1168
1102
|
const message = Sprinkle.ExtractMessage(type, `Enter a string for ${path.join(".")}`);
|
|
1169
1103
|
let answer;
|
|
1170
|
-
if (isSensitive(type)) {
|
|
1171
|
-
answer = await (0, _prompts.
|
|
1104
|
+
if ((0, _typeGuards.isSensitive)(type)) {
|
|
1105
|
+
answer = await (0, _prompts.passwordCancellable)({
|
|
1172
1106
|
message
|
|
1173
1107
|
});
|
|
1174
1108
|
} else {
|
|
1175
|
-
answer = await (0, _prompts.
|
|
1109
|
+
answer = await (0, _prompts.inputCancellable)({
|
|
1176
1110
|
message,
|
|
1177
1111
|
default: defaultString
|
|
1178
1112
|
});
|
|
1179
|
-
|
|
1113
|
+
if (answer !== null) {
|
|
1114
|
+
this.defaults["string"] = answer;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
if (answer === null) {
|
|
1118
|
+
throw new _types.UserCancelledError();
|
|
1180
1119
|
}
|
|
1181
1120
|
return answer;
|
|
1182
1121
|
}
|
|
1183
|
-
if (isBigInt(type)) {
|
|
1184
|
-
const answer = await (0, _prompts.
|
|
1122
|
+
if ((0, _typeGuards.isBigInt)(type)) {
|
|
1123
|
+
const answer = await (0, _prompts.inputCancellable)({
|
|
1185
1124
|
message: Sprinkle.ExtractMessage(type, `Enter a bigint for ${path.join(".")}`),
|
|
1186
1125
|
default: def ? def.toString() : undefined,
|
|
1187
1126
|
validate: s => {
|
|
@@ -1193,12 +1132,15 @@ class Sprinkle {
|
|
|
1193
1132
|
}
|
|
1194
1133
|
}
|
|
1195
1134
|
});
|
|
1135
|
+
if (answer === null) {
|
|
1136
|
+
throw new _types.UserCancelledError();
|
|
1137
|
+
}
|
|
1196
1138
|
return BigInt(answer);
|
|
1197
1139
|
}
|
|
1198
|
-
if (isLiteral(type)) {
|
|
1140
|
+
if ((0, _typeGuards.isLiteral)(type)) {
|
|
1199
1141
|
return type.const;
|
|
1200
1142
|
}
|
|
1201
|
-
if (isObject(type)) {
|
|
1143
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1202
1144
|
const obj = {};
|
|
1203
1145
|
const fields = type["properties"];
|
|
1204
1146
|
for (const [field, fieldType] of Object.entries(fields)) {
|
|
@@ -1209,14 +1151,14 @@ class Sprinkle {
|
|
|
1209
1151
|
}
|
|
1210
1152
|
|
|
1211
1153
|
//TODO: support starting with default values for arrays and allow removal of items
|
|
1212
|
-
if (isArray(type)) {
|
|
1154
|
+
if ((0, _typeGuards.isArray)(type)) {
|
|
1213
1155
|
const arr = [];
|
|
1214
1156
|
const itemType = type.items;
|
|
1215
1157
|
let addMore = true;
|
|
1216
1158
|
while (addMore) {
|
|
1217
1159
|
const itemValue = await this._fillInStruct(itemType, path.concat([`[${arr.length}]`]), defs);
|
|
1218
1160
|
arr.push(itemValue);
|
|
1219
|
-
const continueAnswer = await (0, _prompts.
|
|
1161
|
+
const continueAnswer = await (0, _prompts.selectCancellable)({
|
|
1220
1162
|
message: `Add another item to ${path.join(".")}?`,
|
|
1221
1163
|
choices: [{
|
|
1222
1164
|
name: "Yes",
|
|
@@ -1226,11 +1168,14 @@ class Sprinkle {
|
|
|
1226
1168
|
value: false
|
|
1227
1169
|
}]
|
|
1228
1170
|
});
|
|
1171
|
+
if (continueAnswer === null) {
|
|
1172
|
+
throw new _types.UserCancelledError();
|
|
1173
|
+
}
|
|
1229
1174
|
addMore = continueAnswer;
|
|
1230
1175
|
}
|
|
1231
1176
|
return arr;
|
|
1232
1177
|
}
|
|
1233
|
-
if (isTuple(type)) {
|
|
1178
|
+
if ((0, _typeGuards.isTuple)(type)) {
|
|
1234
1179
|
const items = type.items ?? [];
|
|
1235
1180
|
const result = [];
|
|
1236
1181
|
for (let i = 0; i < items.length; i++) {
|
|
@@ -1243,7 +1188,7 @@ class Sprinkle {
|
|
|
1243
1188
|
throw new Error(`Unable to fill in struct for type at path ${path.join(".")}`);
|
|
1244
1189
|
}
|
|
1245
1190
|
resolveType(type, path, defs) {
|
|
1246
|
-
if (isRef(type) || isThis(type) || isImport(type)) {
|
|
1191
|
+
if ((0, _typeGuards.isRef)(type) || (0, _typeGuards.isThis)(type) || (0, _typeGuards.isImport)(type)) {
|
|
1247
1192
|
defs = {
|
|
1248
1193
|
...defs,
|
|
1249
1194
|
...type.$defs
|
|
@@ -1263,10 +1208,10 @@ class Sprinkle {
|
|
|
1263
1208
|
if ("description" in type) {
|
|
1264
1209
|
return type.description;
|
|
1265
1210
|
}
|
|
1266
|
-
if (isLiteral(type)) {
|
|
1211
|
+
if ((0, _typeGuards.isLiteral)(type)) {
|
|
1267
1212
|
return `${type.const}`;
|
|
1268
1213
|
}
|
|
1269
|
-
if (isObject(type)) {
|
|
1214
|
+
if ((0, _typeGuards.isObject)(type)) {
|
|
1270
1215
|
const fields = type["properties"];
|
|
1271
1216
|
if ("type" in fields) {
|
|
1272
1217
|
return Sprinkle.ExtractMessage(fields["type"], def);
|