@hardkas/accounts 0.11.0-alpha → 0.11.2-alpha

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.
@@ -0,0 +1,46 @@
1
+ // src/signer-backend.ts
2
+ async function loadKaspaWasm() {
3
+ try {
4
+ return await import("kaspa-wasm");
5
+ } catch (error) {
6
+ const err = new Error(
7
+ "SIGNER_BACKEND_UNAVAILABLE: Official Kaspa WASM backend is required to sign transactions.\nInstall it via: npm install kaspa-wasm"
8
+ );
9
+ err.code = "SIGNER_BACKEND_UNAVAILABLE";
10
+ throw err;
11
+ }
12
+ }
13
+ function detectCapabilities(sdk) {
14
+ let v1 = false;
15
+ if (sdk.createTransaction && sdk.createTransaction.length >= 8) {
16
+ v1 = true;
17
+ }
18
+ if (sdk.createV1Transaction || sdk.Transaction && sdk.Transaction.prototype && sdk.Transaction.prototype.computeBudget) {
19
+ v1 = true;
20
+ }
21
+ return { transactionV1Signing: v1 };
22
+ }
23
+ async function getKaspaSigningBackendStatus() {
24
+ try {
25
+ const sdk = await loadKaspaWasm();
26
+ return {
27
+ available: true,
28
+ name: "Kaspa WASM SDK",
29
+ version: sdk.version || "unknown",
30
+ capabilities: detectCapabilities(sdk)
31
+ };
32
+ } catch (error) {
33
+ return {
34
+ available: false,
35
+ name: "None",
36
+ error: error instanceof Error ? error.message : String(error),
37
+ capabilities: { transactionV1Signing: false }
38
+ };
39
+ }
40
+ }
41
+
42
+ export {
43
+ loadKaspaWasm,
44
+ detectCapabilities,
45
+ getKaspaSigningBackendStatus
46
+ };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { HardkasConfig } from '@hardkas/config';
2
2
  import { TxPlanArtifact, SignedTxArtifact, ExternalHardkasSigner, HardkasArtifactBase } from '@hardkas/artifacts';
3
3
  import { NetworkId } from '@hardkas/core';
4
+ import { TxPlan } from '@hardkas/tx-builder';
4
5
 
5
6
  type HardkasAccountKind = "simulated" | "kaspa-private-key" | "external-wallet" | "evm-private-key";
6
7
  interface KeystorePayload {
@@ -162,12 +163,21 @@ interface KaspaSigningBackendStatus {
162
163
  name: string;
163
164
  version?: string;
164
165
  error?: string;
166
+ capabilities: {
167
+ transactionV1Signing: boolean;
168
+ };
165
169
  }
166
170
  /**
167
171
  * Loads the official Kaspa WASM SDK dynamically.
168
172
  * This ensures the toolkit remains usable even if the SDK is not installed.
169
173
  */
170
174
  declare function loadKaspaWasm(): Promise<any>;
175
+ /**
176
+ * Detects the specific capabilities supported by the installed kaspa-wasm SDK.
177
+ */
178
+ declare function detectCapabilities(sdk: any): {
179
+ transactionV1Signing: boolean;
180
+ };
171
181
  /**
172
182
  * Checks if the Kaspa WASM SDK is available without throwing.
173
183
  */
@@ -297,7 +307,7 @@ declare function resolveRealAccountOrAddress(store: RealAccountStore | null, nam
297
307
  };
298
308
 
299
309
  interface RealTxSigningInput {
300
- readonly plan: TxPlanArtifact;
310
+ readonly plan: TxPlan;
301
311
  readonly account: RealDevAccount;
302
312
  }
303
313
  interface RealTxSigningResult {
@@ -522,4 +532,4 @@ declare class WalletStateStoreJson {
522
532
  nextChangeIndex(walletId: string): number;
523
533
  }
524
534
 
525
- export { AddressManager, type ChainType, type CreateKaspaWalletOptions, DEV_ACCOUNTS_PASSWORD, type DeriveRequest, type DerivedAddress, type EncryptedKeystoreV2, type EvmExportResult, type GeneratedKaspaDevAccount, type HardkasAccount, type HardkasAccountKind, type HardkasBaseAccount, type HardkasEvmPrivateKeyAccount, type HardkasExternalWalletAccount, HardkasFixtureSigner, type HardkasKaspaPrivateKeyAccount, type HardkasSigner, type HardkasSignerKind, type HardkasSimulatedAccount, type HardkasTxPlanSigner, type HelperDeriveRequest, type KaspaKeyGenerator, KaspaSdkKeyGenerator, type KaspaSdkKeyGeneratorOptions, KaspaSdkRealTxSigner, type KaspaSdkRealTxSignerOptions, type KaspaSigningBackendStatus, KaspaWasmPrivateKeySigner, type KeystoreCipherParams, type KeystoreKdfParams, KeystoreManager, type KeystorePayload, type KeystoreUnlockResult, type NetworkType, type PathRequest, type RealAccountStore, type RealDevAccount, type RealTxSigner, type RealTxSigningInput, type RealTxSigningResult, type ResolveAccountOptions, type SignTxPlanInput, type SignTxPlanResult, SimulatedSigner, SimulatedTxPlanSigner, UnsupportedKaspaKeyGenerator, UnsupportedRealKaspaSigner, UnsupportedRealTxSigner, type WalletArtifact, type WalletClaims, type WalletCreateRequest, type WalletImportRequest, WalletManager, WalletManagerImpl, type WalletMetadata, type WalletState, WalletStateStoreJson, type WalletStateStoreOptions, appendToKeystoreJson, assertSigningNetworkAllowed, createEmptyRealAccountStore, createLocalKaspaWallet, describeAccount, ensureDevAccounts, getDefaultRealAccountsPath, getKaspaSigningBackendStatus, getOrCreateDevAccount, getRealDevAccount, getRequiredEnv, importRealDevAccount, listDevAccountsSync, listHardkasAccounts, listRealDevAccounts, loadKaspaWasm, loadOrCreateRealAccountStore, loadRealAccountStore, loadRealAccountStoreSync, prepareEvmAccountExport, removeRealDevAccount, resolveHardkasAccount, resolveHardkasAccountAddress, resolveRealAccountOrAddress, saveRealAccountStore, signTxPlanArtifact, validateAccountName, validateAddressNetwork, validateAddressPrefix, withKeystoreLock };
535
+ export { AddressManager, type ChainType, type CreateKaspaWalletOptions, DEV_ACCOUNTS_PASSWORD, type DeriveRequest, type DerivedAddress, type EncryptedKeystoreV2, type EvmExportResult, type GeneratedKaspaDevAccount, type HardkasAccount, type HardkasAccountKind, type HardkasBaseAccount, type HardkasEvmPrivateKeyAccount, type HardkasExternalWalletAccount, HardkasFixtureSigner, type HardkasKaspaPrivateKeyAccount, type HardkasSigner, type HardkasSignerKind, type HardkasSimulatedAccount, type HardkasTxPlanSigner, type HelperDeriveRequest, type KaspaKeyGenerator, KaspaSdkKeyGenerator, type KaspaSdkKeyGeneratorOptions, KaspaSdkRealTxSigner, type KaspaSdkRealTxSignerOptions, type KaspaSigningBackendStatus, KaspaWasmPrivateKeySigner, type KeystoreCipherParams, type KeystoreKdfParams, KeystoreManager, type KeystorePayload, type KeystoreUnlockResult, type NetworkType, type PathRequest, type RealAccountStore, type RealDevAccount, type RealTxSigner, type RealTxSigningInput, type RealTxSigningResult, type ResolveAccountOptions, type SignTxPlanInput, type SignTxPlanResult, SimulatedSigner, SimulatedTxPlanSigner, UnsupportedKaspaKeyGenerator, UnsupportedRealKaspaSigner, UnsupportedRealTxSigner, type WalletArtifact, type WalletClaims, type WalletCreateRequest, type WalletImportRequest, WalletManager, WalletManagerImpl, type WalletMetadata, type WalletState, WalletStateStoreJson, type WalletStateStoreOptions, appendToKeystoreJson, assertSigningNetworkAllowed, createEmptyRealAccountStore, createLocalKaspaWallet, describeAccount, detectCapabilities, ensureDevAccounts, getDefaultRealAccountsPath, getKaspaSigningBackendStatus, getOrCreateDevAccount, getRealDevAccount, getRequiredEnv, importRealDevAccount, listDevAccountsSync, listHardkasAccounts, listRealDevAccounts, loadKaspaWasm, loadOrCreateRealAccountStore, loadRealAccountStore, loadRealAccountStoreSync, prepareEvmAccountExport, removeRealDevAccount, resolveHardkasAccount, resolveHardkasAccountAddress, resolveRealAccountOrAddress, saveRealAccountStore, signTxPlanArtifact, validateAccountName, validateAddressNetwork, validateAddressPrefix, withKeystoreLock };
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ detectCapabilities,
3
+ getKaspaSigningBackendStatus,
4
+ loadKaspaWasm
5
+ } from "./chunk-7QKDZQBR.js";
6
+
1
7
  // src/simulated.ts
2
8
  var SimulatedSigner = class {
3
9
  constructor(account) {
@@ -534,35 +540,6 @@ import {
534
540
  } from "@hardkas/artifacts";
535
541
  import { systemRuntimeContext } from "@hardkas/core";
536
542
 
537
- // src/signer-backend.ts
538
- async function loadKaspaWasm() {
539
- try {
540
- return await import("kaspa-wasm");
541
- } catch (error) {
542
- const err = new Error(
543
- "SIGNER_BACKEND_UNAVAILABLE: Official Kaspa WASM backend is required to sign transactions.\nInstall it via: npm install kaspa-wasm"
544
- );
545
- err.code = "SIGNER_BACKEND_UNAVAILABLE";
546
- throw err;
547
- }
548
- }
549
- async function getKaspaSigningBackendStatus() {
550
- try {
551
- const sdk = await loadKaspaWasm();
552
- return {
553
- available: true,
554
- name: "Kaspa WASM SDK",
555
- version: sdk.version || "unknown"
556
- };
557
- } catch (error) {
558
- return {
559
- available: false,
560
- name: "None",
561
- error: error instanceof Error ? error.message : String(error)
562
- };
563
- }
564
- }
565
-
566
543
  // src/kaspa-wasm-signer.ts
567
544
  import { calculateContentHash } from "@hardkas/artifacts";
568
545
 
@@ -930,6 +907,13 @@ var KaspaWasmPrivateKeySigner = class {
930
907
  const plan = input.planArtifact;
931
908
  const account = this.options.account;
932
909
  const sdk = await loadKaspaWasm();
910
+ const { detectCapabilities: detectCapabilities2 } = await import("./signer-backend-T4JT2RCK.js");
911
+ const capabilities = detectCapabilities2(sdk);
912
+ if (plan.computeBudget !== void 0 || plan.outputs.some((o) => o.covenant)) {
913
+ if (!capabilities.transactionV1Signing) {
914
+ throw new Error("Transaction V1 signing is not supported by the installed kaspa-wasm version");
915
+ }
916
+ }
933
917
  assertSigningNetworkAllowed({
934
918
  network: plan.networkId,
935
919
  mode: plan.mode,
@@ -1424,11 +1408,6 @@ var KaspaSdkRealTxSigner = class {
1424
1408
  if (!account.privateKey) {
1425
1409
  throw new Error("Account has no private key available for signing.");
1426
1410
  }
1427
- if (plan.from.address !== account.address) {
1428
- throw new Error(
1429
- `Address mismatch: Plan requires ${plan.from.address}, but account has ${account.address}.`
1430
- );
1431
- }
1432
1411
  try {
1433
1412
  const privateKey = new sdk.PrivateKey(account.privateKey);
1434
1413
  const utxos = plan.inputs.map((u) => {
@@ -1437,19 +1416,30 @@ var KaspaSdkRealTxSigner = class {
1437
1416
  `UTXO ${u.outpoint.transactionId}:${u.outpoint.index} is missing scriptPublicKey required for signing.`
1438
1417
  );
1439
1418
  }
1440
- const spk = u.scriptPublicKey;
1441
- return new sdk.UtxoEntry(
1442
- BigInt(u.amountSompi),
1443
- spk,
1444
- u.outpoint.transactionId,
1445
- u.outpoint.index,
1446
- plan.from.address
1447
- );
1419
+ let spkHex = String(u.scriptPublicKey);
1420
+ let spkVersion = 0;
1421
+ if (spkHex.length >= 68) {
1422
+ spkVersion = parseInt(spkHex.slice(0, 4), 16) || 0;
1423
+ spkHex = spkHex.slice(4);
1424
+ }
1425
+ return {
1426
+ address: account.address,
1427
+ outpoint: {
1428
+ transactionId: u.outpoint.transactionId,
1429
+ index: u.outpoint.index
1430
+ },
1431
+ utxoEntry: {
1432
+ amount: BigInt(u.amountSompi),
1433
+ scriptPublicKey: new sdk.ScriptPublicKey(spkVersion, spkHex),
1434
+ blockDaaScore: BigInt(u.blockDaaScore ?? 0),
1435
+ isCoinbase: u.isCoinbase ?? false
1436
+ }
1437
+ };
1448
1438
  });
1449
- const outputs = [
1450
- new sdk.PaymentOutput(new sdk.Address(plan.to.address), BigInt(plan.amountSompi))
1451
- ];
1452
- const changeAddress = plan.change ? new sdk.Address(plan.change.address) : void 0;
1439
+ const outputs = plan.outputs.map(
1440
+ (o) => new sdk.PaymentOutput(new sdk.Address(o.address), BigInt(o.amountSompi))
1441
+ );
1442
+ const changeAddress = plan.change ? plan.change.address : account.address;
1453
1443
  const priorityFee = BigInt(plan.estimatedFeeSompi);
1454
1444
  const unsignedTx = sdk.createTransaction(
1455
1445
  utxos,
@@ -1458,17 +1448,22 @@ var KaspaSdkRealTxSigner = class {
1458
1448
  priorityFee
1459
1449
  );
1460
1450
  const signedTx = sdk.signTransaction(unsignedTx, [privateKey], true);
1461
- const payload = signedTx.serialize ? signedTx.serialize() : JSON.stringify(signedTx.toRpcTransaction());
1462
- const txId = signedTx.id;
1451
+ const innerTx = signedTx.tx;
1452
+ const txId = innerTx?.id;
1453
+ const payload = JSON.stringify(
1454
+ innerTx.toJSON(),
1455
+ (_k, v) => typeof v === "bigint" ? v.toString() : v
1456
+ );
1463
1457
  return {
1464
1458
  signedTransaction: {
1465
1459
  format: "kaspa-sdk",
1466
- payload
1460
+ payload,
1461
+ raw: innerTx
1467
1462
  },
1468
1463
  txId
1469
1464
  };
1470
1465
  } catch (e) {
1471
- const msg = e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e);
1466
+ const msg = e instanceof Error ? e.message : String(e);
1472
1467
  if (msg.includes("is not a constructor") || msg.includes("is not a function")) {
1473
1468
  throw new Error(
1474
1469
  `Kaspa SDK signer adapter could not find required transaction signing primitives: ${msg}`
@@ -1560,6 +1555,8 @@ async function appendToKeystoreJson(workspaceRoot, alias, accountData) {
1560
1555
 
1561
1556
  // src/address-manager.ts
1562
1557
  import { createHash } from "crypto";
1558
+ import { createRequire } from "module";
1559
+ var require2 = createRequire(import.meta.url);
1563
1560
  function resolveChain(chain) {
1564
1561
  if (chain === "receive" || chain === 0) return 0;
1565
1562
  if (chain === "change" || chain === 1) return 1;
@@ -1588,9 +1585,16 @@ var AddressManager = {
1588
1585
  addressIndex: opts.addressIndex
1589
1586
  });
1590
1587
  const payload = `${opts.seedRef}:${derivationPath}:${network}`;
1591
- const hash = createHash("sha256").update(payload).digest("hex").slice(0, 42);
1592
- const prefix = network.includes("sim") ? "kaspasim" : "kaspatest";
1593
- const address = `${prefix}:q${hash}`;
1588
+ const hash = createHash("sha256").update(payload).digest("hex");
1589
+ let address;
1590
+ try {
1591
+ const kaspa = require2("kaspa-wasm");
1592
+ const priv = new kaspa.PrivateKey(hash);
1593
+ address = priv.toKeypair().toAddress(network).toString();
1594
+ } catch (e) {
1595
+ const prefix = network.includes("sim") ? "kaspasim" : "kaspatest";
1596
+ address = `${prefix}:q${hash.slice(0, 42)}`;
1597
+ }
1594
1598
  return {
1595
1599
  address,
1596
1600
  path: derivationPath,
@@ -1791,6 +1795,7 @@ export {
1791
1795
  createEmptyRealAccountStore,
1792
1796
  createLocalKaspaWallet,
1793
1797
  describeAccount,
1798
+ detectCapabilities,
1794
1799
  ensureDevAccounts,
1795
1800
  getDefaultRealAccountsPath,
1796
1801
  getKaspaSigningBackendStatus,
@@ -0,0 +1,10 @@
1
+ import {
2
+ detectCapabilities,
3
+ getKaspaSigningBackendStatus,
4
+ loadKaspaWasm
5
+ } from "./chunk-7QKDZQBR.js";
6
+ export {
7
+ detectCapabilities,
8
+ getKaspaSigningBackendStatus,
9
+ loadKaspaWasm
10
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/accounts",
3
- "version": "0.11.0-alpha",
3
+ "version": "0.11.2-alpha",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -19,10 +19,11 @@
19
19
  "dependencies": {
20
20
  "hash-wasm": "^4.12.0",
21
21
  "kaspa-wasm": "0.13.0",
22
- "@hardkas/artifacts": "0.11.0-alpha",
23
- "@hardkas/config": "0.11.0-alpha",
24
- "@hardkas/core": "0.11.0-alpha",
25
- "@hardkas/localnet": "0.11.0-alpha"
22
+ "@hardkas/artifacts": "0.11.2-alpha",
23
+ "@hardkas/config": "0.11.2-alpha",
24
+ "@hardkas/core": "0.11.2-alpha",
25
+ "@hardkas/tx-builder": "0.11.2-alpha",
26
+ "@hardkas/localnet": "0.11.2-alpha"
26
27
  },
27
28
  "devDependencies": {
28
29
  "tsup": "^8.3.5",