@dynamic-labs-wallet/node-midnight 0.0.0 → 1.0.115

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/index.cjs ADDED
@@ -0,0 +1,1092 @@
1
+ 'use strict';
2
+
3
+ var node = require('@dynamic-labs-wallet/node');
4
+ var ledger = require('@midnight-ntwrk/ledger-v8');
5
+ var walletSdkAddressFormat = require('@midnight-ntwrk/wallet-sdk-address-format');
6
+ var bip32 = require('@scure/bip32');
7
+ var bech32 = require('bech32');
8
+
9
+ function _interopNamespaceDefault(e) {
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var ledger__namespace = /*#__PURE__*/_interopNamespaceDefault(ledger);
27
+
28
+ /**
29
+ * Facade network tag: which Midnight network the wallet runtime (relay, indexer,
30
+ * proof server, sync state) operates against. Distinct from the numeric
31
+ * replay-protection id below.
32
+ */ // 0 = non-mainnet, 1 = Mainnet — baked into the transaction hash to prevent
33
+ // cross-network replay.
34
+ var MIDNIGHT_NETWORK_IDS = {
35
+ mainnet: 1,
36
+ preview: 0,
37
+ preprod: 0,
38
+ undeployed: 0
39
+ };
40
+ /**
41
+ * Resolves a caller-supplied network identifier (numeric 0/1, network name, or
42
+ * `midnight:<network>` chainId) to the facade network tag. Defaults to 'preview'.
43
+ */ var resolveMidnightNetworkTag = function(networkId) {
44
+ if (networkId === undefined || networkId === null) return 'preview';
45
+ if (typeof networkId === 'number') return networkId === 1 ? 'mainnet' : 'preview';
46
+ var name = networkId.includes(':') ? networkId.split(':')[1] : networkId;
47
+ return name === 'mainnet' ? 'mainnet' : 'preview';
48
+ };
49
+ var ERROR_KEYGEN_FAILED = 'Error with keygen';
50
+ var ERROR_CREATE_WALLET_ACCOUNT = 'Error creating midnight wallet account';
51
+ var ERROR_IMPORT_PRIVATE_KEY = 'Error importing private key';
52
+ var ERROR_EXPORT_PRIVATE_KEY = 'Error exporting private key';
53
+ var ERROR_SIGN_MESSAGE = 'Error signing message';
54
+ var ERROR_ACCOUNT_ADDRESS_REQUIRED = 'Account address is required';
55
+
56
+ function _array_like_to_array$1(arr, len) {
57
+ if (len == null || len > arr.length) len = arr.length;
58
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
59
+ return arr2;
60
+ }
61
+ function _array_with_holes$1(arr) {
62
+ if (Array.isArray(arr)) return arr;
63
+ }
64
+ function _iterable_to_array_limit$1(arr, i) {
65
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
66
+ if (_i == null) return;
67
+ var _arr = [];
68
+ var _n = true;
69
+ var _d = false;
70
+ var _s, _e;
71
+ try {
72
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
73
+ _arr.push(_s.value);
74
+ if (i && _arr.length === i) break;
75
+ }
76
+ } catch (err) {
77
+ _d = true;
78
+ _e = err;
79
+ } finally{
80
+ try {
81
+ if (!_n && _i["return"] != null) _i["return"]();
82
+ } finally{
83
+ if (_d) throw _e;
84
+ }
85
+ }
86
+ return _arr;
87
+ }
88
+ function _non_iterable_rest$1() {
89
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
90
+ }
91
+ function _sliced_to_array$1(arr, i) {
92
+ return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$1(arr, i) || _non_iterable_rest$1();
93
+ }
94
+ function _unsupported_iterable_to_array$1(o, minLen) {
95
+ if (!o) return;
96
+ if (typeof o === "string") return _array_like_to_array$1(o, minLen);
97
+ var n = Object.prototype.toString.call(o).slice(8, -1);
98
+ if (n === "Object" && o.constructor) n = o.constructor.name;
99
+ if (n === "Map" || n === "Set") return Array.from(n);
100
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
101
+ }
102
+ /** Bech32m HRPs (BIP-0350) for Midnight unshielded addresses, per network. */ var ADDRESS_PREFIXES = {
103
+ mainnet: 'mn_addr',
104
+ preview: 'mn_addr_preview',
105
+ preprod: 'mn_addr_preprod',
106
+ undeployed: 'mn_addr_undeployed'
107
+ };
108
+ /**
109
+ * Encodes a 32-byte Midnight address hash as a bech32m address.
110
+ *
111
+ * The input is the *address hash* (`ledger.addressFromKey()` — a Poseidon hash
112
+ * of the verifying key), not the raw public key. Use {@link addressHashFromPublicKey}
113
+ * to produce it.
114
+ */ var deriveMidnightAddress = function(param) {
115
+ var addressHashHex = param.addressHashHex, _param_network = param.network, network = _param_network === void 0 ? 'preview' : _param_network;
116
+ var bytes = Buffer.from(addressHashHex, 'hex');
117
+ if (bytes.length !== 32) {
118
+ throw new Error("Invalid address hash length: ".concat(bytes.length, ", expected 32"));
119
+ }
120
+ return bech32.bech32m.encode(ADDRESS_PREFIXES[network], bech32.bech32m.toWords(bytes));
121
+ };
122
+ // `'mn_addr'` is a strict prefix of every other value in ADDRESS_PREFIXES,
123
+ // so naive `startsWith` checks hit `mainnet` for any Midnight address. Always
124
+ // check longest prefix first (descending).
125
+ var PREFIX_ENTRIES_LONGEST_FIRST = Object.entries(ADDRESS_PREFIXES).slice().sort(function(a, b) {
126
+ return b[1].length - a[1].length;
127
+ });
128
+ var isValidMidnightAddress = function(address) {
129
+ try {
130
+ var hasValidPrefix = PREFIX_ENTRIES_LONGEST_FIRST.some(function(param) {
131
+ var _param = _sliced_to_array$1(param, 2), prefix = _param[1];
132
+ return address.startsWith(prefix);
133
+ });
134
+ if (!hasValidPrefix) return false;
135
+ var decoded = bech32.bech32m.decode(address, 120);
136
+ return Buffer.from(bech32.bech32m.fromWords(decoded.words)).length === 32;
137
+ } catch (e) {
138
+ return false;
139
+ }
140
+ };
141
+ var decodeMidnightAddress = function(address) {
142
+ if (!isValidMidnightAddress(address)) {
143
+ throw new Error('Invalid Midnight address');
144
+ }
145
+ var decoded = bech32.bech32m.decode(address, 120);
146
+ return Buffer.from(bech32.bech32m.fromWords(decoded.words));
147
+ };
148
+ var getNetworkFromAddress = function(address) {
149
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
150
+ try {
151
+ for(var _iterator = PREFIX_ENTRIES_LONGEST_FIRST[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
152
+ var _step_value = _sliced_to_array$1(_step.value, 2), network = _step_value[0], prefix = _step_value[1];
153
+ if (address.startsWith(prefix)) {
154
+ return network;
155
+ }
156
+ }
157
+ } catch (err) {
158
+ _didIteratorError = true;
159
+ _iteratorError = err;
160
+ } finally{
161
+ try {
162
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
163
+ _iterator.return();
164
+ }
165
+ } finally{
166
+ if (_didIteratorError) {
167
+ throw _iteratorError;
168
+ }
169
+ }
170
+ }
171
+ throw new Error('Unknown network prefix in Midnight address');
172
+ };
173
+ /**
174
+ * Normalizes an MPC-returned BIP340 public key to the 32-byte x-only hex form
175
+ * that `ledger.addressFromKey()` expects, dropping the 02/03 parity byte if the
176
+ * key arrived in 33-byte compressed form.
177
+ */ var toXOnlyPublicKeyHex = function(publicKeyHex) {
178
+ var normalized = publicKeyHex.startsWith('0x') ? publicKeyHex.slice(2) : publicKeyHex;
179
+ if (normalized.length === 66 && (normalized.startsWith('02') || normalized.startsWith('03'))) {
180
+ return normalized.slice(2);
181
+ }
182
+ if (normalized.length === 64) {
183
+ return normalized;
184
+ }
185
+ throw new Error("Invalid BIP340 public key length: ".concat(normalized.length, " hex chars, expected 64 or 66"));
186
+ };
187
+
188
+ function _array_like_to_array(arr, len) {
189
+ if (len == null || len > arr.length) len = arr.length;
190
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
191
+ return arr2;
192
+ }
193
+ function _array_with_holes(arr) {
194
+ if (Array.isArray(arr)) return arr;
195
+ }
196
+ function _assert_this_initialized(self) {
197
+ if (self === void 0) {
198
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
199
+ }
200
+ return self;
201
+ }
202
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
203
+ try {
204
+ var info = gen[key](arg);
205
+ var value = info.value;
206
+ } catch (error) {
207
+ reject(error);
208
+ return;
209
+ }
210
+ if (info.done) {
211
+ resolve(value);
212
+ } else {
213
+ Promise.resolve(value).then(_next, _throw);
214
+ }
215
+ }
216
+ function _async_to_generator(fn) {
217
+ return function() {
218
+ var self = this, args = arguments;
219
+ return new Promise(function(resolve, reject) {
220
+ var gen = fn.apply(self, args);
221
+ function _next(value) {
222
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
223
+ }
224
+ function _throw(err) {
225
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
226
+ }
227
+ _next(undefined);
228
+ });
229
+ };
230
+ }
231
+ function _call_super(_this, derived, args) {
232
+ derived = _get_prototype_of(derived);
233
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
234
+ }
235
+ function _class_call_check(instance, Constructor) {
236
+ if (!(instance instanceof Constructor)) {
237
+ throw new TypeError("Cannot call a class as a function");
238
+ }
239
+ }
240
+ function _defineProperties(target, props) {
241
+ for(var i = 0; i < props.length; i++){
242
+ var descriptor = props[i];
243
+ descriptor.enumerable = descriptor.enumerable || false;
244
+ descriptor.configurable = true;
245
+ if ("value" in descriptor) descriptor.writable = true;
246
+ Object.defineProperty(target, descriptor.key, descriptor);
247
+ }
248
+ }
249
+ function _create_class(Constructor, protoProps, staticProps) {
250
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
251
+ return Constructor;
252
+ }
253
+ function _define_property(obj, key, value) {
254
+ if (key in obj) {
255
+ Object.defineProperty(obj, key, {
256
+ value: value,
257
+ enumerable: true,
258
+ configurable: true,
259
+ writable: true
260
+ });
261
+ } else {
262
+ obj[key] = value;
263
+ }
264
+ return obj;
265
+ }
266
+ function _get_prototype_of(o) {
267
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
268
+ return o.__proto__ || Object.getPrototypeOf(o);
269
+ };
270
+ return _get_prototype_of(o);
271
+ }
272
+ function _inherits(subClass, superClass) {
273
+ if (typeof superClass !== "function" && superClass !== null) {
274
+ throw new TypeError("Super expression must either be null or a function");
275
+ }
276
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
277
+ constructor: {
278
+ value: subClass,
279
+ writable: true,
280
+ configurable: true
281
+ }
282
+ });
283
+ if (superClass) _set_prototype_of(subClass, superClass);
284
+ }
285
+ function _instanceof(left, right) {
286
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
287
+ return !!right[Symbol.hasInstance](left);
288
+ } else {
289
+ return left instanceof right;
290
+ }
291
+ }
292
+ function _iterable_to_array_limit(arr, i) {
293
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
294
+ if (_i == null) return;
295
+ var _arr = [];
296
+ var _n = true;
297
+ var _d = false;
298
+ var _s, _e;
299
+ try {
300
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
301
+ _arr.push(_s.value);
302
+ if (i && _arr.length === i) break;
303
+ }
304
+ } catch (err) {
305
+ _d = true;
306
+ _e = err;
307
+ } finally{
308
+ try {
309
+ if (!_n && _i["return"] != null) _i["return"]();
310
+ } finally{
311
+ if (_d) throw _e;
312
+ }
313
+ }
314
+ return _arr;
315
+ }
316
+ function _non_iterable_rest() {
317
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
318
+ }
319
+ function _possible_constructor_return(self, call) {
320
+ if (call && (_type_of(call) === "object" || typeof call === "function")) {
321
+ return call;
322
+ }
323
+ return _assert_this_initialized(self);
324
+ }
325
+ function _set_prototype_of(o, p) {
326
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
327
+ o.__proto__ = p;
328
+ return o;
329
+ };
330
+ return _set_prototype_of(o, p);
331
+ }
332
+ function _sliced_to_array(arr, i) {
333
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
334
+ }
335
+ function _type_of(obj) {
336
+ "@swc/helpers - typeof";
337
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
338
+ }
339
+ function _unsupported_iterable_to_array(o, minLen) {
340
+ if (!o) return;
341
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
342
+ var n = Object.prototype.toString.call(o).slice(8, -1);
343
+ if (n === "Object" && o.constructor) n = o.constructor.name;
344
+ if (n === "Map" || n === "Set") return Array.from(n);
345
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
346
+ }
347
+ function _is_native_reflect_construct() {
348
+ try {
349
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
350
+ } catch (_) {}
351
+ return (_is_native_reflect_construct = function() {
352
+ return !!result;
353
+ })();
354
+ }
355
+ function _ts_generator(thisArg, body) {
356
+ var f, y, t, g, _ = {
357
+ label: 0,
358
+ sent: function() {
359
+ if (t[0] & 1) throw t[1];
360
+ return t[1];
361
+ },
362
+ trys: [],
363
+ ops: []
364
+ };
365
+ return g = {
366
+ next: verb(0),
367
+ "throw": verb(1),
368
+ "return": verb(2)
369
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
370
+ return this;
371
+ }), g;
372
+ function verb(n) {
373
+ return function(v) {
374
+ return step([
375
+ n,
376
+ v
377
+ ]);
378
+ };
379
+ }
380
+ function step(op) {
381
+ if (f) throw new TypeError("Generator is already executing.");
382
+ while(_)try {
383
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
384
+ if (y = 0, t) op = [
385
+ op[0] & 2,
386
+ t.value
387
+ ];
388
+ switch(op[0]){
389
+ case 0:
390
+ case 1:
391
+ t = op;
392
+ break;
393
+ case 4:
394
+ _.label++;
395
+ return {
396
+ value: op[1],
397
+ done: false
398
+ };
399
+ case 5:
400
+ _.label++;
401
+ y = op[1];
402
+ op = [
403
+ 0
404
+ ];
405
+ continue;
406
+ case 7:
407
+ op = _.ops.pop();
408
+ _.trys.pop();
409
+ continue;
410
+ default:
411
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
412
+ _ = 0;
413
+ continue;
414
+ }
415
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
416
+ _.label = op[1];
417
+ break;
418
+ }
419
+ if (op[0] === 6 && _.label < t[1]) {
420
+ _.label = t[1];
421
+ t = op;
422
+ break;
423
+ }
424
+ if (t && _.label < t[2]) {
425
+ _.label = t[2];
426
+ _.ops.push(op);
427
+ break;
428
+ }
429
+ if (t[2]) _.ops.pop();
430
+ _.trys.pop();
431
+ continue;
432
+ }
433
+ op = body.call(thisArg, _);
434
+ } catch (e) {
435
+ op = [
436
+ 6,
437
+ e
438
+ ];
439
+ y = 0;
440
+ } finally{
441
+ f = t = 0;
442
+ }
443
+ if (op[0] & 5) throw op[1];
444
+ return {
445
+ value: op[0] ? op[1] : void 0,
446
+ done: true
447
+ };
448
+ }
449
+ }
450
+ var logError = node.createLogError('node-midnight');
451
+ // Unshielded is NON-hardened to match the server's MPC signing path (Sodot's
452
+ // derivePrivateKeyFromXpriv is non-hardened-only). Shielded and dust are hardened Midnight-canonical paths; those roles are signed
453
+ // entirely client-side, so the Sodot constraint does not apply.
454
+ var ROLE_DERIVATION_PATHS = {
455
+ unshielded: 'm/44/2400/0/0/0',
456
+ shielded: "m/44'/2400'/0'/3/0",
457
+ dust: "m/44'/2400'/0'/2/0"
458
+ };
459
+ var DynamicMidnightWalletClient = /*#__PURE__*/ function(DynamicWalletClient) {
460
+ _inherits(DynamicMidnightWalletClient, DynamicWalletClient);
461
+ function DynamicMidnightWalletClient(param) {
462
+ var environmentId = param.environmentId, baseApiUrl = param.baseApiUrl, baseMPCRelayApiUrl = param.baseMPCRelayApiUrl, debug = param.debug, enableMPCAccelerator = param.enableMPCAccelerator, logger = param.logger, _param_network = param.network, network = _param_network === void 0 ? 'preview' : _param_network;
463
+ _class_call_check(this, DynamicMidnightWalletClient);
464
+ var _this;
465
+ _this = _call_super(this, DynamicMidnightWalletClient, [
466
+ {
467
+ environmentId: environmentId,
468
+ baseApiUrl: baseApiUrl,
469
+ baseMPCRelayApiUrl: baseMPCRelayApiUrl,
470
+ debug: debug,
471
+ enableMPCAccelerator: enableMPCAccelerator,
472
+ logger: logger
473
+ }
474
+ ]), _define_property(_this, "chainName", 'MIDNIGHT'), _define_property(_this, "network", void 0), /**
475
+ * Derives the bech32m unshielded account address from a BIP340 public key.
476
+ * The address is the Poseidon hash of the verifying key, not the key itself.
477
+ */ _define_property(_this, "deriveAccountAddress", function(param) {
478
+ var publicKeyHex = param.publicKeyHex, network = param.network;
479
+ var addressHashHex = ledger__namespace.addressFromKey(toXOnlyPublicKeyHex(publicKeyHex));
480
+ return deriveMidnightAddress({
481
+ addressHashHex: addressHashHex,
482
+ network: network !== null && network !== void 0 ? network : _this.network
483
+ });
484
+ });
485
+ _this.network = network;
486
+ return _this;
487
+ }
488
+ _create_class(DynamicMidnightWalletClient, [
489
+ {
490
+ key: "createWalletAccount",
491
+ value: /**
492
+ * Creates a new wallet account.
493
+ * @param thresholdSignatureScheme - The threshold signature scheme to use for the wallet.
494
+ * @param password - The password to use for the wallet.
495
+ * @param onError - The function to call if an error occurs.
496
+ * @param backUpToDynamic - Whether to back up the external server key shares to the client share service. By default, it is false.
497
+ * @returns The walletMetadata, public key hex, raw public key, and external server key shares.
498
+ */ function createWalletAccount(param) {
499
+ var thresholdSignatureScheme = param.thresholdSignatureScheme, password = param.password, onError = param.onError, _param_backUpToDynamic = param.backUpToDynamic, backUpToDynamic = _param_backUpToDynamic === void 0 ? false : _param_backUpToDynamic;
500
+ var _this = this;
501
+ return _async_to_generator(function() {
502
+ var resolvedWalletId, resolvedShareSetId, serverAccountAddress, ceremonyCompleteResolver, ceremonyCompletePromise, _ref, rawPublicKey, externalServerKeyShares, publicKeyHex, accountAddress, chainConfig, walletMetadata, _ref1, keySharesWithBackupStatus, backupInfo, error;
503
+ return _ts_generator(this, function(_state) {
504
+ switch(_state.label){
505
+ case 0:
506
+ _state.trys.push([
507
+ 0,
508
+ 4,
509
+ ,
510
+ 5
511
+ ]);
512
+ ceremonyCompletePromise = new Promise(function(resolve) {
513
+ ceremonyCompleteResolver = resolve;
514
+ });
515
+ return [
516
+ 4,
517
+ _this.keyGen({
518
+ thresholdSignatureScheme: thresholdSignatureScheme,
519
+ chainName: _this.chainName,
520
+ password: password,
521
+ backUpToDynamic: backUpToDynamic,
522
+ onError: onError,
523
+ onCeremonyComplete: function(accountAddress, walletId, shareSetId) {
524
+ resolvedWalletId = walletId;
525
+ resolvedShareSetId = shareSetId;
526
+ serverAccountAddress = accountAddress;
527
+ ceremonyCompleteResolver(undefined);
528
+ }
529
+ })
530
+ ];
531
+ case 1:
532
+ _ref = _state.sent(), rawPublicKey = _ref.rawPublicKey, externalServerKeyShares = _ref.externalServerKeyShares;
533
+ return [
534
+ 4,
535
+ ceremonyCompletePromise
536
+ ];
537
+ case 2:
538
+ _state.sent();
539
+ if (!rawPublicKey || !externalServerKeyShares || !resolvedWalletId || !(typeof rawPublicKey === 'string' || _instanceof(rawPublicKey, Uint8Array))) {
540
+ throw new Error(ERROR_KEYGEN_FAILED);
541
+ }
542
+ publicKeyHex = typeof rawPublicKey === 'string' ? rawPublicKey : Buffer.from(rawPublicKey).toString('hex');
543
+ accountAddress = _this.deriveAccountAddress({
544
+ publicKeyHex: publicKeyHex
545
+ });
546
+ // The browser client takes the server's address verbatim because the
547
+ // Poseidon hash is WASM-only there; in Node we derive it locally. Warn
548
+ // rather than throw on divergence — the server's is authoritative.
549
+ if (serverAccountAddress && serverAccountAddress !== accountAddress) {
550
+ _this.logger.warn("[Midnight] Locally derived address ".concat(accountAddress, " differs from server address ").concat(serverAccountAddress));
551
+ }
552
+ chainConfig = node.getMPCChainConfig(_this.chainName);
553
+ walletMetadata = {
554
+ walletId: resolvedWalletId,
555
+ accountAddress: accountAddress,
556
+ chainName: _this.chainName,
557
+ thresholdSignatureScheme: thresholdSignatureScheme,
558
+ derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map(function(value, index) {
559
+ return [
560
+ index,
561
+ value
562
+ ];
563
+ }))),
564
+ shareSetId: resolvedShareSetId
565
+ };
566
+ return [
567
+ 4,
568
+ _this.storeEncryptedBackupByWalletWithRetry({
569
+ accountAddress: accountAddress,
570
+ externalServerKeyShares: externalServerKeyShares,
571
+ password: password,
572
+ backUpToDynamic: backUpToDynamic,
573
+ walletMetadata: walletMetadata
574
+ })
575
+ ];
576
+ case 3:
577
+ _ref1 = _state.sent(), keySharesWithBackupStatus = _ref1.keySharesWithBackupStatus, backupInfo = _ref1.backupInfo;
578
+ walletMetadata.externalServerKeySharesBackupInfo = backupInfo;
579
+ return [
580
+ 2,
581
+ {
582
+ walletMetadata: walletMetadata,
583
+ publicKeyHex: publicKeyHex,
584
+ rawPublicKey: rawPublicKey,
585
+ externalServerKeyShares: externalServerKeyShares,
586
+ externalKeySharesWithBackupStatus: keySharesWithBackupStatus
587
+ }
588
+ ];
589
+ case 4:
590
+ error = _state.sent();
591
+ logError({
592
+ message: ERROR_CREATE_WALLET_ACCOUNT,
593
+ error: error,
594
+ context: {}
595
+ });
596
+ throw new Error(ERROR_CREATE_WALLET_ACCOUNT, {
597
+ cause: error
598
+ });
599
+ case 5:
600
+ return [
601
+ 2
602
+ ];
603
+ }
604
+ });
605
+ })();
606
+ }
607
+ },
608
+ {
609
+ key: "signMessage",
610
+ value: /**
611
+ * Signs a message using MPC
612
+ * @param message - The message to sign
613
+ * @param walletMetadata - Wallet metadata (the full object returned by createWalletAccount/importPrivateKey, with backupInfo merged from any subsequent updatePassword/refresh/reshare)
614
+ * @param password - The password for encrypted backup shares
615
+ * @param externalServerKeyShares - The external server key shares
616
+ * @param onError - The function to call if an error occurs
617
+ * @returns The signature as a base64 string
618
+ */ function signMessage(param) {
619
+ var message = param.message, walletMetadata = param.walletMetadata, _param_password = param.password, password = _param_password === void 0 ? undefined : _param_password, externalServerKeyShares = param.externalServerKeyShares, onError = param.onError;
620
+ var _this = this;
621
+ return _async_to_generator(function() {
622
+ var accountAddress, messageHex, signature, error;
623
+ return _ts_generator(this, function(_state) {
624
+ switch(_state.label){
625
+ case 0:
626
+ accountAddress = walletMetadata.accountAddress;
627
+ if (!accountAddress) {
628
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
629
+ }
630
+ _state.label = 1;
631
+ case 1:
632
+ _state.trys.push([
633
+ 1,
634
+ 3,
635
+ ,
636
+ 4
637
+ ]);
638
+ // The signing API expects hex; policy validation needs the original bytes.
639
+ messageHex = Buffer.from(message).toString('hex');
640
+ return [
641
+ 4,
642
+ _this.sign({
643
+ message: messageHex,
644
+ accountAddress: accountAddress,
645
+ chainName: _this.chainName,
646
+ password: password,
647
+ externalServerKeyShares: externalServerKeyShares,
648
+ onError: onError,
649
+ walletMetadata: walletMetadata,
650
+ context: {
651
+ midnightMessage: message
652
+ }
653
+ })
654
+ ];
655
+ case 2:
656
+ signature = _state.sent();
657
+ return [
658
+ 2,
659
+ Buffer.from(signature).toString('base64')
660
+ ];
661
+ case 3:
662
+ error = _state.sent();
663
+ logError({
664
+ message: ERROR_SIGN_MESSAGE,
665
+ error: error,
666
+ context: {
667
+ accountAddress: accountAddress
668
+ }
669
+ });
670
+ throw new Error(ERROR_SIGN_MESSAGE, {
671
+ cause: error
672
+ });
673
+ case 4:
674
+ return [
675
+ 2
676
+ ];
677
+ }
678
+ });
679
+ })();
680
+ }
681
+ },
682
+ {
683
+ key: "exportPrivateKey",
684
+ value: /**
685
+ * Exports the private key for a given wallet.
686
+ *
687
+ * Returns the unshielded (role 0) key at the wallet's derivation path. The
688
+ * shielded and dust role keys need the master xprv, which `exportKey` does
689
+ * not surface — see the package README.
690
+ *
691
+ * @param walletMetadata - Wallet metadata (the full object returned by createWalletAccount/importPrivateKey, with backupInfo merged from any subsequent updatePassword/refresh/reshare)
692
+ * @param password - The password for encrypted backup shares
693
+ * @param externalServerKeyShares - The external server key shares
694
+ * @returns The private key as a hex string
695
+ */ function exportPrivateKey(param) {
696
+ var walletMetadata = param.walletMetadata, _param_password = param.password, password = _param_password === void 0 ? undefined : _param_password, externalServerKeyShares = param.externalServerKeyShares;
697
+ var _this = this;
698
+ return _async_to_generator(function() {
699
+ var accountAddress, derivedPrivateKey, error;
700
+ return _ts_generator(this, function(_state) {
701
+ switch(_state.label){
702
+ case 0:
703
+ accountAddress = walletMetadata.accountAddress;
704
+ _state.label = 1;
705
+ case 1:
706
+ _state.trys.push([
707
+ 1,
708
+ 3,
709
+ ,
710
+ 4
711
+ ]);
712
+ return [
713
+ 4,
714
+ _this.exportKey({
715
+ accountAddress: accountAddress,
716
+ chainName: _this.chainName,
717
+ password: password,
718
+ externalServerKeyShares: externalServerKeyShares,
719
+ walletMetadata: walletMetadata
720
+ })
721
+ ];
722
+ case 2:
723
+ derivedPrivateKey = _state.sent().derivedPrivateKey;
724
+ if (!derivedPrivateKey) {
725
+ throw new Error('Derived private key is undefined');
726
+ }
727
+ return [
728
+ 2,
729
+ derivedPrivateKey.slice(0, 64)
730
+ ];
731
+ case 3:
732
+ error = _state.sent();
733
+ logError({
734
+ message: ERROR_EXPORT_PRIVATE_KEY,
735
+ error: error,
736
+ context: {
737
+ accountAddress: accountAddress
738
+ }
739
+ });
740
+ throw new Error(ERROR_EXPORT_PRIVATE_KEY);
741
+ case 4:
742
+ return [
743
+ 2
744
+ ];
745
+ }
746
+ });
747
+ })();
748
+ }
749
+ },
750
+ {
751
+ key: "offlineExportPrivateKey",
752
+ value: /**
753
+ * Exports the private key offline using key shares
754
+ * @param keyShares - The key shares to export the private key for
755
+ * @param derivationPath - The derivation path
756
+ * @returns The derived private key
757
+ *
758
+ * `derivationPath` is the JSON-serialized index map that
759
+ * `walletMetadata.derivationPath` carries (e.g. `'{"0":44,"1":2400,"2":0,"3":0,"4":0}'`
760
+ * or `'[44,2400,0,0,0]'`). BIP-32 strings such as `"m/44'/2400'/0'/0/0"` are rejected.
761
+ * Omit it to export without path derivation.
762
+ */ function offlineExportPrivateKey(param) {
763
+ var keyShares = param.keyShares, derivationPath = param.derivationPath;
764
+ var _this = this;
765
+ return _async_to_generator(function() {
766
+ var derivedPrivateKey;
767
+ return _ts_generator(this, function(_state) {
768
+ switch(_state.label){
769
+ case 0:
770
+ return [
771
+ 4,
772
+ _this.offlineExportKey({
773
+ chainName: _this.chainName,
774
+ keyShares: keyShares,
775
+ derivationPath: derivationPath
776
+ })
777
+ ];
778
+ case 1:
779
+ derivedPrivateKey = _state.sent().derivedPrivateKey;
780
+ return [
781
+ 2,
782
+ {
783
+ derivedPrivateKey: derivedPrivateKey
784
+ }
785
+ ];
786
+ }
787
+ });
788
+ })();
789
+ }
790
+ },
791
+ {
792
+ key: "importPrivateKey",
793
+ value: /**
794
+ * Imports a private key.
795
+ * @param privateKey - The private key to import.
796
+ * @param chainName - The chain name to use for the wallet.
797
+ * @param thresholdSignatureScheme - The threshold signature scheme to use for the wallet.
798
+ * @param password - The password to use for the wallet.
799
+ * @param onError - The function to call if an error occurs.
800
+ * @param backUpToDynamic - Whether to back up the external server key shares to the client share service.
801
+ * @param publicAddressCheck - Optional public address to verify against the derived address.
802
+ * @returns The walletMetadata, public key hex, raw public key, and external server key shares.
803
+ */ function importPrivateKey(param) {
804
+ var privateKey = param.privateKey, chainName = param.chainName, thresholdSignatureScheme = param.thresholdSignatureScheme, password = param.password, onError = param.onError, _param_backUpToDynamic = param.backUpToDynamic, backUpToDynamic = _param_backUpToDynamic === void 0 ? false : _param_backUpToDynamic, publicAddressCheck = param.publicAddressCheck;
805
+ var _this = this;
806
+ return _async_to_generator(function() {
807
+ var resolvedWalletId, resolvedShareSetId, ceremonyCompleteResolver, ceremonyCompletePromise, formattedPrivateKey, derivedAddress, _ref, rawPublicKey, externalServerKeyShares, resultPublicKeyHex, accountAddress, chainConfig, walletMetadata, _ref1, keySharesWithBackupStatus, backupInfo, error;
808
+ return _ts_generator(this, function(_state) {
809
+ switch(_state.label){
810
+ case 0:
811
+ _state.trys.push([
812
+ 0,
813
+ 4,
814
+ ,
815
+ 5
816
+ ]);
817
+ ceremonyCompletePromise = new Promise(function(resolve) {
818
+ ceremonyCompleteResolver = resolve;
819
+ });
820
+ formattedPrivateKey = privateKey.startsWith('0x') ? privateKey.slice(2) : privateKey;
821
+ derivedAddress = _this.deriveAccountAddress({
822
+ publicKeyHex: _this.getPublicKeyFromPrivateKey(formattedPrivateKey)
823
+ });
824
+ if (publicAddressCheck && derivedAddress !== publicAddressCheck) {
825
+ throw new Error("Public address mismatch: derived address ".concat(derivedAddress, " !== public address ").concat(publicAddressCheck));
826
+ }
827
+ return [
828
+ 4,
829
+ _this.importRawPrivateKey({
830
+ chainName: chainName,
831
+ thresholdSignatureScheme: thresholdSignatureScheme,
832
+ privateKey: formattedPrivateKey,
833
+ password: password,
834
+ backUpToDynamic: backUpToDynamic,
835
+ onCeremonyComplete: function(_accountAddress, walletId, shareSetId) {
836
+ resolvedWalletId = walletId;
837
+ resolvedShareSetId = shareSetId;
838
+ ceremonyCompleteResolver(undefined);
839
+ },
840
+ onError: function(e) {
841
+ logError({
842
+ message: 'importPrivateKey: onError',
843
+ error: e,
844
+ context: {}
845
+ });
846
+ onError === null || onError === void 0 ? void 0 : onError(e);
847
+ }
848
+ })
849
+ ];
850
+ case 1:
851
+ _ref = _state.sent(), rawPublicKey = _ref.rawPublicKey, externalServerKeyShares = _ref.externalServerKeyShares;
852
+ return [
853
+ 4,
854
+ ceremonyCompletePromise
855
+ ];
856
+ case 2:
857
+ _state.sent();
858
+ if (!rawPublicKey || !externalServerKeyShares || !resolvedWalletId || !(typeof rawPublicKey === 'string' || _instanceof(rawPublicKey, Uint8Array))) {
859
+ throw new Error(ERROR_IMPORT_PRIVATE_KEY);
860
+ }
861
+ resultPublicKeyHex = typeof rawPublicKey === 'string' ? rawPublicKey : Buffer.from(rawPublicKey).toString('hex');
862
+ accountAddress = _this.deriveAccountAddress({
863
+ publicKeyHex: resultPublicKeyHex
864
+ });
865
+ if (accountAddress !== derivedAddress) {
866
+ throw new Error("Public key mismatch: derived address ".concat(accountAddress, " !== expected ").concat(derivedAddress));
867
+ }
868
+ chainConfig = node.getMPCChainConfig(_this.chainName);
869
+ walletMetadata = {
870
+ walletId: resolvedWalletId,
871
+ accountAddress: accountAddress,
872
+ chainName: _this.chainName,
873
+ thresholdSignatureScheme: thresholdSignatureScheme,
874
+ derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map(function(value, index) {
875
+ return [
876
+ index,
877
+ value
878
+ ];
879
+ }))),
880
+ shareSetId: resolvedShareSetId
881
+ };
882
+ return [
883
+ 4,
884
+ _this.storeEncryptedBackupByWalletWithRetry({
885
+ accountAddress: accountAddress,
886
+ externalServerKeyShares: externalServerKeyShares,
887
+ password: password,
888
+ backUpToDynamic: backUpToDynamic,
889
+ walletMetadata: walletMetadata
890
+ })
891
+ ];
892
+ case 3:
893
+ _ref1 = _state.sent(), keySharesWithBackupStatus = _ref1.keySharesWithBackupStatus, backupInfo = _ref1.backupInfo;
894
+ walletMetadata.externalServerKeySharesBackupInfo = backupInfo;
895
+ return [
896
+ 2,
897
+ {
898
+ walletMetadata: walletMetadata,
899
+ publicKeyHex: resultPublicKeyHex,
900
+ rawPublicKey: rawPublicKey,
901
+ externalServerKeyShares: externalServerKeyShares,
902
+ externalKeySharesWithBackupStatus: keySharesWithBackupStatus
903
+ }
904
+ ];
905
+ case 4:
906
+ error = _state.sent();
907
+ logError({
908
+ message: ERROR_IMPORT_PRIVATE_KEY,
909
+ error: error,
910
+ context: {}
911
+ });
912
+ onError === null || onError === void 0 ? void 0 : onError(error);
913
+ throw new Error(ERROR_IMPORT_PRIVATE_KEY);
914
+ case 5:
915
+ return [
916
+ 2
917
+ ];
918
+ }
919
+ });
920
+ })();
921
+ }
922
+ },
923
+ {
924
+ /**
925
+ * Derives the BIP340 verifying key from a private key
926
+ * @param privateKeyHex - The private key as a hex string
927
+ * @returns The verifying key as a hex string
928
+ */ key: "getPublicKeyFromPrivateKey",
929
+ value: function getPublicKeyFromPrivateKey(privateKeyHex) {
930
+ try {
931
+ var privateKeyBytes = Buffer.from(privateKeyHex, 'hex');
932
+ if (privateKeyBytes.length !== 32) {
933
+ throw new Error("Invalid private key length: ".concat(privateKeyBytes.length, ", expected 32"));
934
+ }
935
+ return ledger__namespace.signatureVerifyingKey(privateKeyHex);
936
+ } catch (error) {
937
+ // Deliberately not logging the error: it originates from a WASM call that
938
+ // received the private key, so its message could echo key material into
939
+ // logs. The error is re-thrown intact for the caller to inspect.
940
+ this.logger.debug('[Midnight] getPublicKeyFromPrivateKey failed');
941
+ throw error;
942
+ }
943
+ }
944
+ },
945
+ {
946
+ key: "getRoleKeys",
947
+ value: /**
948
+ * Derives the unshielded, shielded, and dust role keys from the wallet's MPC
949
+ * master xprv.
950
+ *
951
+ * Deliberately not persisted: these are plaintext secrets, and writing them
952
+ * to disk or a cache would trade a per-session MPC export for a durable
953
+ * exfiltration target. Callers should hold the result only as long as the
954
+ * operation needs it.
955
+ *
956
+ * @returns The three role private keys as hex strings
957
+ */ function getRoleKeys(param) {
958
+ var walletMetadata = param.walletMetadata, _param_password = param.password, password = _param_password === void 0 ? undefined : _param_password, externalServerKeyShares = param.externalServerKeyShares, elevatedAccessToken = param.elevatedAccessToken;
959
+ var _this = this;
960
+ return _async_to_generator(function() {
961
+ var keyExportRaw, master, roleKeys;
962
+ return _ts_generator(this, function(_state) {
963
+ switch(_state.label){
964
+ case 0:
965
+ return [
966
+ 4,
967
+ _this.exportMasterKeyMaterial({
968
+ accountAddress: walletMetadata.accountAddress,
969
+ chainName: _this.chainName,
970
+ password: password,
971
+ externalServerKeyShares: externalServerKeyShares,
972
+ elevatedAccessToken: elevatedAccessToken,
973
+ walletMetadata: walletMetadata
974
+ })
975
+ ];
976
+ case 1:
977
+ keyExportRaw = _state.sent().keyExportRaw;
978
+ master = bip32.HDKey.fromExtendedKey(keyExportRaw);
979
+ roleKeys = Object.entries(ROLE_DERIVATION_PATHS).map(function(param) {
980
+ var _param = _sliced_to_array(param, 2), role = _param[0], path = _param[1];
981
+ var privateKey = master.derive(path).privateKey;
982
+ if (!privateKey) {
983
+ throw new Error("BIP32 derivation returned null privateKey for the ".concat(role, " role"));
984
+ }
985
+ return [
986
+ role,
987
+ Buffer.from(privateKey).toString('hex')
988
+ ];
989
+ });
990
+ return [
991
+ 2,
992
+ Object.fromEntries(roleKeys)
993
+ ];
994
+ }
995
+ });
996
+ })();
997
+ }
998
+ },
999
+ {
1000
+ key: "getAddresses",
1001
+ value: /**
1002
+ * Derives the wallet's three receiving addresses.
1003
+ *
1004
+ * Only the unshielded address comes from the MPC keygen (secp256k1/BIP340);
1005
+ * shielded uses JubJub and dust BLS12-381, so both are derived client-side
1006
+ * from the role keys. Requires an MPC export, but no facade or sync.
1007
+ *
1008
+ * @returns bech32m addresses for the requested network
1009
+ */ function getAddresses(access) {
1010
+ var _this = this;
1011
+ return _async_to_generator(function() {
1012
+ var network, encodeId, roleKeys, shieldedSecretKeys, shielded, dust, dustSecretKey;
1013
+ return _ts_generator(this, function(_state) {
1014
+ switch(_state.label){
1015
+ case 0:
1016
+ network = resolveMidnightNetworkTag(access.networkId);
1017
+ // Preview keeps the bare tag; mainnet is the library's `mainnet` symbol.
1018
+ encodeId = network === 'mainnet' ? walletSdkAddressFormat.mainnet : 'preview';
1019
+ return [
1020
+ 4,
1021
+ _this.getRoleKeys(access)
1022
+ ];
1023
+ case 1:
1024
+ roleKeys = _state.sent();
1025
+ shieldedSecretKeys = ledger__namespace.ZswapSecretKeys.fromSeed(new Uint8Array(Buffer.from(roleKeys.shielded, 'hex')));
1026
+ shielded = walletSdkAddressFormat.MidnightBech32m.encode(encodeId, new walletSdkAddressFormat.ShieldedAddress(new walletSdkAddressFormat.ShieldedCoinPublicKey(Buffer.from(shieldedSecretKeys.coinPublicKey, 'hex')), new walletSdkAddressFormat.ShieldedEncryptionPublicKey(Buffer.from(shieldedSecretKeys.encryptionPublicKey, 'hex')))).toString();
1027
+ try {
1028
+ dustSecretKey = ledger__namespace.DustSecretKey.fromSeed(new Uint8Array(Buffer.from(roleKeys.dust, 'hex')));
1029
+ dust = walletSdkAddressFormat.MidnightBech32m.encode(encodeId, new walletSdkAddressFormat.DustAddress(dustSecretKey.publicKey)).toString();
1030
+ } catch (err) {
1031
+ _this.logger.warn('[Midnight] getAddresses: dust address derivation failed', err);
1032
+ }
1033
+ return [
1034
+ 2,
1035
+ {
1036
+ unshielded: access.walletMetadata.accountAddress,
1037
+ shielded: shielded,
1038
+ dust: dust
1039
+ }
1040
+ ];
1041
+ }
1042
+ });
1043
+ })();
1044
+ }
1045
+ },
1046
+ {
1047
+ key: "getMidnightWallets",
1048
+ value: /**
1049
+ * Gets all Midnight wallets
1050
+ * @returns Array of Midnight wallets
1051
+ */ function getMidnightWallets() {
1052
+ var _this = this;
1053
+ return _async_to_generator(function() {
1054
+ var wallets;
1055
+ return _ts_generator(this, function(_state) {
1056
+ switch(_state.label){
1057
+ case 0:
1058
+ return [
1059
+ 4,
1060
+ _this.getWallets()
1061
+ ];
1062
+ case 1:
1063
+ wallets = _state.sent();
1064
+ return [
1065
+ 2,
1066
+ wallets.filter(function(wallet) {
1067
+ return wallet.chainName === _this.chainName;
1068
+ })
1069
+ ];
1070
+ }
1071
+ });
1072
+ })();
1073
+ }
1074
+ }
1075
+ ]);
1076
+ return DynamicMidnightWalletClient;
1077
+ }(node.DynamicWalletClient);
1078
+
1079
+ exports.DynamicMidnightWalletClient = DynamicMidnightWalletClient;
1080
+ exports.ERROR_ACCOUNT_ADDRESS_REQUIRED = ERROR_ACCOUNT_ADDRESS_REQUIRED;
1081
+ exports.ERROR_CREATE_WALLET_ACCOUNT = ERROR_CREATE_WALLET_ACCOUNT;
1082
+ exports.ERROR_EXPORT_PRIVATE_KEY = ERROR_EXPORT_PRIVATE_KEY;
1083
+ exports.ERROR_IMPORT_PRIVATE_KEY = ERROR_IMPORT_PRIVATE_KEY;
1084
+ exports.ERROR_KEYGEN_FAILED = ERROR_KEYGEN_FAILED;
1085
+ exports.ERROR_SIGN_MESSAGE = ERROR_SIGN_MESSAGE;
1086
+ exports.MIDNIGHT_NETWORK_IDS = MIDNIGHT_NETWORK_IDS;
1087
+ exports.decodeMidnightAddress = decodeMidnightAddress;
1088
+ exports.deriveMidnightAddress = deriveMidnightAddress;
1089
+ exports.getNetworkFromAddress = getNetworkFromAddress;
1090
+ exports.isValidMidnightAddress = isValidMidnightAddress;
1091
+ exports.resolveMidnightNetworkTag = resolveMidnightNetworkTag;
1092
+ exports.toXOnlyPublicKeyHex = toXOnlyPublicKeyHex;