@hardkas/accounts 0.12.0-rc.2 → 0.12.0-rc.20

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.
@@ -2,7 +2,8 @@ import {
2
2
  LazyAccountAuthorizer,
3
3
  PrivateKeyAuthorizer,
4
4
  StaticSignatureScriptAuthorizer
5
- } from "./chunk-YJL7P33W.js";
5
+ } from "./chunk-5266LO4K.js";
6
+ import "./chunk-MCKGQKYU.js";
6
7
  export {
7
8
  LazyAccountAuthorizer,
8
9
  PrivateKeyAuthorizer,
@@ -1,4 +1,5 @@
1
1
  // src/authorizers.ts
2
+ import { getNetworkPrefix } from "@hardkas/core";
2
3
  var StaticSignatureScriptAuthorizer = class {
3
4
  constructor(signatureScript) {
4
5
  this.signatureScript = signatureScript;
@@ -30,7 +31,7 @@ var PrivateKeyAuthorizer = class {
30
31
  const { wasm, wasmTransaction, inputIndex } = ctx;
31
32
  const privateKey = new wasm.PrivateKey(this.privateKeyHex);
32
33
  const networkId = context.plan.networkId || "simnet";
33
- const expectedAddress = privateKey.toKeypair().toAddress(networkId).toString();
34
+ const expectedAddress = privateKey.toKeypair().toAddress(getNetworkPrefix(networkId)).toString();
34
35
  if (planInput.address && expectedAddress !== planInput.address) {
35
36
  throw new Error(
36
37
  `PRIVATE_KEY_DOES_NOT_CONTROL_INPUT: The provided private key for account '${this.accountName}' derives to address '${expectedAddress}', but input ${context.inputIndex} is controlled by '${planInput.address}'.`
@@ -38,9 +39,7 @@ var PrivateKeyAuthorizer = class {
38
39
  }
39
40
  const tx = wasmTransaction;
40
41
  try {
41
- console.log("DEBUG: Calling signTransaction");
42
42
  const signedTx = wasm.signTransaction(tx, [privateKey], false);
43
- console.log("DEBUG: signTransaction OK");
44
43
  const sigScript = signedTx.inputs[inputIndex].signatureScript;
45
44
  if (!sigScript || sigScript.length === 0) {
46
45
  throw new Error(`UNAUTHORIZED_TRANSACTION_INPUT: Kaspa WASM failed to generate a signature script for input ${inputIndex} using account '${this.accountName}'.`);
@@ -63,7 +62,7 @@ var LazyAccountAuthorizer = class {
63
62
  accountName;
64
63
  workspaceRoot;
65
64
  async authorize(context) {
66
- const { resolveHardkasAccount } = await import("./resolve-GHZEED5L.js");
65
+ const { resolveHardkasAccount } = await import("./resolve-UTFZTVAK.js");
67
66
  const account = await resolveHardkasAccount({
68
67
  nameOrAddress: this.accountName,
69
68
  config: { cwd: this.workspaceRoot }
@@ -74,8 +73,8 @@ var LazyAccountAuthorizer = class {
74
73
  }
75
74
  if (!pkValue && account.keystorePath) {
76
75
  try {
77
- const { KeystoreManager } = await import("./keystore-CMWEKGBF.js");
78
- const { DEV_ACCOUNTS_PASSWORD } = await import("./dev-accounts-B6ZVTPCW.js");
76
+ const { KeystoreManager } = await import("./keystore-2KRHVGCM.js");
77
+ const { DEV_ACCOUNTS_PASSWORD } = await import("./dev-accounts-S4WHPHJK.js");
79
78
  const keystore = await KeystoreManager.loadEncryptedKeystore(account.keystorePath);
80
79
  const unlock = await KeystoreManager.decryptEncryptedKeystore(keystore, DEV_ACCOUNTS_PASSWORD);
81
80
  if (unlock.success && unlock.payload) {
@@ -0,0 +1,15 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+ var __commonJS = (cb, mod) => function __require2() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+
12
+ export {
13
+ __require,
14
+ __commonJS
15
+ };
@@ -219,7 +219,7 @@ function resolveHardkasAccount(options) {
219
219
  let alias = nameOrAddress;
220
220
  if (alias === "0") alias = "alice";
221
221
  if (alias === "1") alias = "bob";
222
- const accounts = listHardkasAccounts(config);
222
+ const accounts = listHardkasAccounts(config, options.executionTarget);
223
223
  const found = accounts.find((a) => a.name === alias);
224
224
  if (found) {
225
225
  return found;
@@ -229,17 +229,63 @@ function resolveHardkasAccount(options) {
229
229
  `Unknown HardKAS account '${nameOrAddress}'. Available accounts: ${available}`
230
230
  );
231
231
  }
232
- function listHardkasAccounts(config) {
232
+ function assertAccountCompatible(account, target) {
233
+ if (account.kind === "synthetic" && target.mode !== "simulator") {
234
+ throw new AccountNetworkMismatchError({
235
+ expected: `Execution mode 'simulator'`,
236
+ actual: `Execution mode '${target.mode}'`,
237
+ detail: `Account '${account.name}' is a synthetic simulator account and cannot be used with mode '${target.mode}'.`
238
+ });
239
+ }
240
+ if ("network" in account && account.network && target.network && account.network !== target.network) {
241
+ throw new AccountNetworkMismatchError({
242
+ expected: target.network,
243
+ actual: account.network,
244
+ detail: `Account '${account.name}' is bound to network '${account.network}' but execution target is '${target.network}'.`
245
+ });
246
+ }
247
+ }
248
+ function listHardkasAccounts(config, executionTarget) {
233
249
  const accounts = /* @__PURE__ */ new Map();
250
+ let targetMode = "localnet";
251
+ if (executionTarget) {
252
+ targetMode = executionTarget.mode;
253
+ } else {
254
+ const execConfig = config?.execution;
255
+ if (execConfig) {
256
+ if (execConfig.mode) {
257
+ targetMode = execConfig.mode;
258
+ } else if (execConfig.default) {
259
+ const targetName = execConfig.default;
260
+ const target = execConfig.targets?.[targetName];
261
+ if (target?.mode) {
262
+ targetMode = target.mode;
263
+ } else if (targetName === "simulator") {
264
+ targetMode = "simulator";
265
+ }
266
+ }
267
+ } else if (config?.defaultNetwork === "simulated") {
268
+ targetMode = "simulator";
269
+ }
270
+ }
234
271
  const detAccounts = createDeterministicAccounts();
235
272
  for (const det of detAccounts) {
236
- accounts.set(det.name, {
237
- name: det.name,
238
- kind: "synthetic",
239
- executionMode: "simulator",
240
- address: det.address,
241
- evmAddress: det.evmAddress
242
- });
273
+ if (targetMode === "simulator") {
274
+ accounts.set(det.name, {
275
+ name: det.name,
276
+ kind: "synthetic",
277
+ executionMode: "simulator",
278
+ address: `kaspa:sim_${det.name}`,
279
+ evmAddress: det.evmAddress
280
+ });
281
+ } else {
282
+ accounts.set(det.name, {
283
+ name: det.name,
284
+ kind: "kaspa",
285
+ network: "simnet",
286
+ address: det.address
287
+ });
288
+ }
243
289
  }
244
290
  const workspaceRoot = config?.cwd || process.cwd();
245
291
  const devAccountsDir = path2.join(workspaceRoot, ".hardkas", "dev-accounts");
@@ -255,13 +301,23 @@ function listHardkasAccounts(config) {
255
301
  if (!keystore.metadata?.network) {
256
302
  throw new AccountNetworkMismatchError({ expected: "known network", actual: "undefined", detail: `at ${path2.join(devAccountsDir, file)}` });
257
303
  }
258
- accounts.set(name, {
259
- name,
260
- kind: "kaspa",
261
- network: keystore.metadata.network,
262
- address: keystore.payload?.address || keystore.metadata?.address,
263
- keystorePath: path2.join(devAccountsDir, file)
264
- });
304
+ if (targetMode === "simulator") {
305
+ accounts.set(name, {
306
+ name,
307
+ kind: "synthetic",
308
+ executionMode: "simulator",
309
+ address: `kaspa:sim_${name}`,
310
+ keystorePath: path2.join(devAccountsDir, file)
311
+ });
312
+ } else {
313
+ accounts.set(name, {
314
+ name,
315
+ kind: "kaspa",
316
+ network: keystore.metadata.network,
317
+ address: keystore.payload?.address || keystore.metadata?.address,
318
+ keystorePath: path2.join(devAccountsDir, file)
319
+ });
320
+ }
265
321
  }
266
322
  } catch (e) {
267
323
  if (e instanceof AccountNetworkMismatchError) throw e;
@@ -275,19 +331,15 @@ function listHardkasAccounts(config) {
275
331
  const data = fs2.readFileSync(keystoreJsonPath, "utf-8");
276
332
  const ks = JSON.parse(data);
277
333
  for (const [name, acc] of Object.entries(ks)) {
278
- const existing = accounts.get(name);
279
- const configKind = acc.type === "simulated" ? "synthetic" : "kaspa";
280
- if (existing && existing.kind !== configKind) {
281
- console.error(`COLLISION DETECTED for ${name}. existing:`, existing, `configKind:`, configKind, `workspaceRoot:`, workspaceRoot, `keystoreJsonPath:`, keystoreJsonPath);
282
- throw new CrossWorldAccountCollisionError({ accountId: name, worlds: [existing.kind, configKind] });
283
- }
284
334
  if (acc.type === "simulated") {
285
- accounts.set(name, {
286
- name,
287
- kind: "synthetic",
288
- executionMode: "simulator",
289
- address: acc.address
290
- });
335
+ if (targetMode === "simulator") {
336
+ accounts.set(name, {
337
+ name,
338
+ kind: "synthetic",
339
+ executionMode: "simulator",
340
+ address: acc.address
341
+ });
342
+ }
291
343
  } else {
292
344
  if (!acc.network) {
293
345
  throw new AccountNetworkMismatchError({ expected: "known network", actual: "undefined", detail: "in keystore.json" });
@@ -450,6 +502,7 @@ export {
450
502
  listRealDevAccounts,
451
503
  resolveRealAccountOrAddress,
452
504
  resolveHardkasAccount,
505
+ assertAccountCompatible,
453
506
  listHardkasAccounts,
454
507
  resolveHardkasAccountAddress,
455
508
  describeAccount
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-R5P3WIWR.js";
4
4
  import {
5
5
  resolveHardkasAccount
6
- } from "./chunk-TRVIQTIO.js";
6
+ } from "./chunk-YBNHOFVX.js";
7
7
  import {
8
8
  loadKaspaWasm
9
9
  } from "./chunk-6DPO5V3N.js";
@@ -15,10 +15,11 @@ import {
15
15
  import fs from "fs";
16
16
  import path from "path";
17
17
  import crypto from "crypto";
18
- import { deterministicCompare } from "@hardkas/core";
18
+ import { deterministicCompare, getNetworkPrefix as getNetworkPrefix2 } from "@hardkas/core";
19
19
 
20
20
  // src/kaspa-wasm-signer.ts
21
21
  import { calculateContentHash } from "@hardkas/artifacts";
22
+ import { getNetworkPrefix } from "@hardkas/core";
22
23
  var KaspaWasmPrivateKeySigner = class {
23
24
  constructor(options) {
24
25
  this.options = options;
@@ -28,7 +29,7 @@ var KaspaWasmPrivateKeySigner = class {
28
29
  async signTxPlan(input) {
29
30
  const plan = input.planArtifact;
30
31
  const sdk = await loadKaspaWasm(this.options.wasmConfig);
31
- const { detectCapabilities } = await import("./signer-backend-W3LNCQA3.js");
32
+ const { detectCapabilities } = await import("./signer-backend-X3FD3XMB.js");
32
33
  const capabilities = detectCapabilities(sdk);
33
34
  if (plan.computeBudget !== void 0 || plan.outputs.some((o) => o.covenant)) {
34
35
  if (!capabilities.transactionV1Signing) {
@@ -55,8 +56,8 @@ var KaspaWasmPrivateKeySigner = class {
55
56
  }
56
57
  if (!pkValue && account.keystorePath) {
57
58
  try {
58
- const KeystoreManager2 = (await import("./keystore-CMWEKGBF.js")).KeystoreManager;
59
- const DEV_ACCOUNTS_PASSWORD2 = (await import("./dev-accounts-B6ZVTPCW.js")).DEV_ACCOUNTS_PASSWORD;
59
+ const KeystoreManager2 = (await import("./keystore-2KRHVGCM.js")).KeystoreManager;
60
+ const DEV_ACCOUNTS_PASSWORD2 = (await import("./dev-accounts-S4WHPHJK.js")).DEV_ACCOUNTS_PASSWORD;
60
61
  const keystore = await KeystoreManager2.loadEncryptedKeystore(account.keystorePath);
61
62
  const unlock = await KeystoreManager2.decryptEncryptedKeystore(keystore, DEV_ACCOUNTS_PASSWORD2);
62
63
  if (unlock.success && unlock.payload) {
@@ -75,8 +76,8 @@ var KaspaWasmPrivateKeySigner = class {
75
76
  err.code = "INVALID_PRIVATE_KEY_MATERIAL";
76
77
  throw err;
77
78
  }
78
- const expectedAddress = new sdk.PrivateKey(pkValue).toKeypair().toAddress(plan.networkId || "simnet").toString();
79
- const { PrivateKeyAuthorizer } = await import("./authorizers-OVWWAL5J.js");
79
+ const expectedAddress = new sdk.PrivateKey(pkValue).toKeypair().toAddress(getNetworkPrefix(plan.networkId || "simnet")).toString();
80
+ const { PrivateKeyAuthorizer } = await import("./authorizers-S5IKSHTE.js");
80
81
  const sourceInputs = plan.inputs || plan.selectedUtxos || [];
81
82
  for (let i = 0; i < numInputs; i++) {
82
83
  if (!authorizers[i]) {
@@ -93,7 +94,6 @@ var KaspaWasmPrivateKeySigner = class {
93
94
  }
94
95
  }
95
96
  try {
96
- console.log("DEBUG PLAN INPUTS:", JSON.stringify(plan.inputs || plan.selectedUtxos, null, 2));
97
97
  const sourceInputs = plan.inputs || plan.selectedUtxos || [];
98
98
  const utxos = sourceInputs.map((u) => {
99
99
  if (!u.outpoint.transactionId || u.outpoint.index === void 0) {
@@ -105,15 +105,27 @@ var KaspaWasmPrivateKeySigner = class {
105
105
  "UTXO is missing scriptPublicKey. Real signing flows must never fabricate cryptographic state."
106
106
  );
107
107
  }
108
+ let spkHex = "";
109
+ let spkVersion = 0;
110
+ if (typeof spk === "object" && spk !== null) {
111
+ spkVersion = Number(spk.version ?? 0);
112
+ spkHex = String(spk.scriptPublicKey || spk.script || "");
113
+ } else {
114
+ spkHex = String(spk);
115
+ if (/^[0-9a-fA-F]{72}$/.test(spkHex) && spkHex.startsWith("0000")) {
116
+ spkVersion = parseInt(spkHex.slice(0, 4), 16) || 0;
117
+ spkHex = spkHex.slice(4);
118
+ }
119
+ }
108
120
  return {
109
- address: plan.from.address,
121
+ address: u.address || plan.from.address,
110
122
  outpoint: {
111
123
  transactionId: u.outpoint.transactionId,
112
124
  index: u.outpoint.index
113
125
  },
114
126
  utxoEntry: {
115
127
  amount: BigInt(u.amountSompi),
116
- scriptPublicKey: new sdk.ScriptPublicKey(parseInt(spk.substring(0, 4), 16) || 0, spk.substring(4)),
128
+ scriptPublicKey: new sdk.ScriptPublicKey(spkVersion, spkHex),
117
129
  blockDaaScore: BigInt(u.blockDaaScore || "0"),
118
130
  isCoinbase: !!u.isCoinbase
119
131
  }
@@ -142,9 +154,6 @@ var KaspaWasmPrivateKeySigner = class {
142
154
  }
143
155
  return new sdk.PaymentOutput(new sdk.Address(o.address), BigInt(o.amountSompi));
144
156
  });
145
- console.log("DEBUG: Calling V1 createTransaction with:", { utxos: utxos.length, wasmOutputs: wasmOutputs.length, priorityFee });
146
- console.log("DEBUG KASPA-WASM PATH:", import.meta.resolve("kaspa-wasm"));
147
- console.log("DEBUG CREATE TRANSACTION FN:", sdk.createTransaction.toString());
148
157
  unsignedTx = sdk.createTransaction(
149
158
  utxos,
150
159
  wasmOutputs,
@@ -183,8 +192,7 @@ var KaspaWasmPrivateKeySigner = class {
183
192
  amount: BigInt(o.amountSompi)
184
193
  };
185
194
  });
186
- console.log("DEBUG: Calling V0 createTransaction with:", { utxos: utxos.length, wasmOutputs: wasmOutputs.length, priorityFee });
187
- const dummyChange = plan.change?.address || plan.from.address;
195
+ const dummyChange = plan.change && plan.change.address || (typeof plan.from === "string" ? plan.from : plan.from?.address) || plan.outputs && plan.outputs[0] && plan.outputs[0].address;
188
196
  unsignedTx = sdk.createTransaction(
189
197
  utxos,
190
198
  wasmOutputs,
@@ -202,7 +210,6 @@ var KaspaWasmPrivateKeySigner = class {
202
210
  inputs[i].sigOpCount = 0;
203
211
  }
204
212
  }
205
- console.log("DEBUG createFreshTx RETURNING:", unsignedTx?.constructor?.name);
206
213
  return unsignedTx;
207
214
  };
208
215
  const inputOverrides = {};
@@ -245,8 +252,6 @@ var KaspaWasmPrivateKeySigner = class {
245
252
  const finalTx = createFreshTx();
246
253
  const signedTx = finalTx;
247
254
  const wasmTxStr = typeof signedTx.serializeToJSON === "function" ? signedTx.serializeToJSON() : signedTx.toString();
248
- console.log("DEBUG wasmTxStr:", wasmTxStr);
249
- console.log("DEBUG: about to parseWasmTxToRpc");
250
255
  const rpcTx = parseWasmTxToRpc(wasmTxStr, signedTx, inputOverrides, plan);
251
256
  const rawTx = JSON.stringify(rpcTx);
252
257
  return {
@@ -263,8 +268,6 @@ var KaspaWasmPrivateKeySigner = class {
263
268
  }
264
269
  };
265
270
  } catch (error) {
266
- console.error("DEBUG SIGNING ERROR:", error);
267
- console.error("DEBUG STACK:", error?.stack || "NO STACK (raw panic)");
268
271
  throw new Error(
269
272
  `Kaspa WASM signing failed: ${error instanceof Error ? error.stack || error.message : JSON.stringify(error, Object.getOwnPropertyNames(error))}`
270
273
  );
@@ -290,6 +293,8 @@ async function ensureDevAccounts(workspaceDir) {
290
293
  }
291
294
  await getOrCreateDevAccount(workspaceDir, 0, "alice");
292
295
  await getOrCreateDevAccount(workspaceDir, 1, "bob");
296
+ await getOrCreateDevAccount(workspaceDir, 2, "carol");
297
+ await getOrCreateDevAccount(workspaceDir, 3, "dave");
293
298
  }
294
299
  async function getOrCreateDevAccount(workspaceDir, index, alias) {
295
300
  const devAccountsDir = path.join(workspaceDir, ".hardkas", "dev-accounts");
@@ -320,20 +325,11 @@ async function getOrCreateDevAccount(workspaceDir, index, alias) {
320
325
  let publicKey = "";
321
326
  try {
322
327
  if (isSimnet) {
323
- let kaspaWasm;
324
- try {
325
- kaspaWasm = await import(
326
- /* @vite-ignore */
327
- "kaspa-wasm"
328
- );
329
- } catch (e) {
330
- console.warn(`
331
- [Warning] kaspa-wasm is not installed. Required for simnet.`);
332
- return { address: "", privateKey: "", publicKey: "" };
333
- }
328
+ const { loadKaspaWasm: loadKaspaWasm2 } = await import("./signer-backend-X3FD3XMB.js");
329
+ const kaspaWasm = await loadKaspaWasm2();
334
330
  const privKey = new kaspaWasm.PrivateKey(privateKeyHex);
335
331
  const kp = privKey.toKeypair();
336
- address = kp.toAddress(network).toString();
332
+ address = kp.toAddress(getNetworkPrefix2(network)).toString();
337
333
  publicKey = kp.publicKey;
338
334
  privateKey = privateKeyHex;
339
335
  } else {
@@ -341,7 +337,7 @@ async function getOrCreateDevAccount(workspaceDir, index, alias) {
341
337
  try {
342
338
  sdkModule = await import(
343
339
  /* @vite-ignore */
344
- "@kaspa/core-lib"
340
+ "./core-lib-YKSIDZOW.js"
345
341
  );
346
342
  } catch (e) {
347
343
  console.warn(`
@@ -355,7 +351,7 @@ async function getOrCreateDevAccount(workspaceDir, index, alias) {
355
351
  const privKey = new sdk.PrivateKey(privateKeyHex);
356
352
  const pubKey = privKey.toPublicKey();
357
353
  try {
358
- address = pubKey.toAddress(network).toString();
354
+ address = pubKey.toAddress(getNetworkPrefix2(network)).toString();
359
355
  } catch (e) {
360
356
  const msg = e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e);
361
357
  if (msg.includes("Second argument must be") || msg.includes("Unsupported")) {