@hardkas/accounts 0.7.0-alpha → 0.7.1-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.
package/dist/index.d.ts CHANGED
@@ -367,4 +367,12 @@ declare class KeystoreManager {
367
367
  static saveEncryptedKeystore(filePath: string, keystore: EncryptedKeystoreV2): Promise<void>;
368
368
  }
369
369
 
370
- export { type CreateKaspaWalletOptions, type EncryptedKeystoreV2, type EvmExportResult, type GeneratedKaspaDevAccount, type HardkasAccount, type HardkasAccountKind, type HardkasBaseAccount, type HardkasEvmPrivateKeyAccount, type HardkasExternalWalletAccount, type HardkasKaspaPrivateKeyAccount, type HardkasSigner, type HardkasSignerKind, type HardkasSimulatedAccount, type HardkasTxPlanSigner, type KaspaKeyGenerator, KaspaSdkKeyGenerator, type KaspaSdkKeyGeneratorOptions, KaspaSdkRealTxSigner, type KaspaSdkRealTxSignerOptions, type KaspaSigningBackendStatus, KaspaWasmPrivateKeySigner, type KeystoreCipherParams, type KeystoreKdfParams, KeystoreManager, type KeystorePayload, type KeystoreUnlockResult, type RealAccountStore, type RealDevAccount, type RealTxSigner, type RealTxSigningInput, type RealTxSigningResult, type ResolveAccountOptions, type SignTxPlanInput, type SignTxPlanResult, SimulatedSigner, SimulatedTxPlanSigner, UnsupportedKaspaKeyGenerator, UnsupportedRealKaspaSigner, UnsupportedRealTxSigner, assertSigningNetworkAllowed, createEmptyRealAccountStore, createLocalKaspaWallet, describeAccount, getDefaultRealAccountsPath, getKaspaSigningBackendStatus, getRealDevAccount, getRequiredEnv, importRealDevAccount, listHardkasAccounts, listRealDevAccounts, loadKaspaWasm, loadOrCreateRealAccountStore, loadRealAccountStore, loadRealAccountStoreSync, prepareEvmAccountExport, removeRealDevAccount, resolveHardkasAccount, resolveHardkasAccountAddress, resolveRealAccountOrAddress, saveRealAccountStore, signTxPlanArtifact, validateAccountName, validateAddressPrefix };
370
+ declare const DEV_ACCOUNTS_PASSWORD = "hardkas-local-dev";
371
+ declare function ensureDevAccounts(workspaceDir: string): Promise<void>;
372
+ declare function getOrCreateDevAccount(workspaceDir: string, index: number, alias: string): Promise<GeneratedKaspaDevAccount>;
373
+ declare function listDevAccountsSync(workspaceDir: string): {
374
+ name: string;
375
+ address: string;
376
+ }[];
377
+
378
+ export { type CreateKaspaWalletOptions, DEV_ACCOUNTS_PASSWORD, type EncryptedKeystoreV2, type EvmExportResult, type GeneratedKaspaDevAccount, type HardkasAccount, type HardkasAccountKind, type HardkasBaseAccount, type HardkasEvmPrivateKeyAccount, type HardkasExternalWalletAccount, type HardkasKaspaPrivateKeyAccount, type HardkasSigner, type HardkasSignerKind, type HardkasSimulatedAccount, type HardkasTxPlanSigner, type KaspaKeyGenerator, KaspaSdkKeyGenerator, type KaspaSdkKeyGeneratorOptions, KaspaSdkRealTxSigner, type KaspaSdkRealTxSignerOptions, type KaspaSigningBackendStatus, KaspaWasmPrivateKeySigner, type KeystoreCipherParams, type KeystoreKdfParams, KeystoreManager, type KeystorePayload, type KeystoreUnlockResult, type RealAccountStore, type RealDevAccount, type RealTxSigner, type RealTxSigningInput, type RealTxSigningResult, type ResolveAccountOptions, type SignTxPlanInput, type SignTxPlanResult, SimulatedSigner, SimulatedTxPlanSigner, UnsupportedKaspaKeyGenerator, UnsupportedRealKaspaSigner, UnsupportedRealTxSigner, 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, validateAddressPrefix };
package/dist/index.js CHANGED
@@ -156,15 +156,34 @@ function resolveHardkasAccount(options) {
156
156
  address: nameOrAddress
157
157
  };
158
158
  }
159
- if (config?.accounts && config.accounts[nameOrAddress]) {
160
- const accConfig = config.accounts[nameOrAddress];
159
+ let alias = nameOrAddress;
160
+ if (alias === "0") alias = "alice";
161
+ if (alias === "1") alias = "bob";
162
+ const workspaceRoot = config?.cwd || process.cwd();
163
+ const devAccountPath = path2.join(workspaceRoot, ".hardkas", "dev-accounts", `${alias}.json`);
164
+ if (fs2.existsSync(devAccountPath)) {
165
+ try {
166
+ const data = fs2.readFileSync(devAccountPath, "utf-8");
167
+ const keystore = JSON.parse(data);
168
+ if (keystore.type === "hardkas.encryptedKeystore.v2") {
169
+ return {
170
+ name: alias,
171
+ kind: "kaspa-private-key",
172
+ address: keystore.metadata?.address
173
+ };
174
+ }
175
+ } catch (e) {
176
+ }
177
+ }
178
+ if (config?.accounts && config.accounts[alias]) {
179
+ const accConfig = config.accounts[alias];
161
180
  return {
162
- name: nameOrAddress,
181
+ name: alias,
163
182
  ...accConfig
164
183
  };
165
184
  }
166
185
  const realStore = loadRealAccountStoreSync();
167
- const realAcc = realStore ? getRealDevAccount(realStore, nameOrAddress) : null;
186
+ const realAcc = realStore ? getRealDevAccount(realStore, alias) : null;
168
187
  if (realAcc) {
169
188
  return {
170
189
  name: realAcc.name,
@@ -174,7 +193,7 @@ function resolveHardkasAccount(options) {
174
193
  };
175
194
  }
176
195
  const detAccounts = createDeterministicAccounts();
177
- const det = detAccounts.find((a) => a.name === nameOrAddress);
196
+ const det = detAccounts.find((a) => a.name === alias);
178
197
  if (det) {
179
198
  return {
180
199
  name: det.name,
@@ -197,6 +216,28 @@ function listHardkasAccounts(config) {
197
216
  evmAddress: det.evmAddress
198
217
  });
199
218
  }
219
+ const workspaceRoot = config?.cwd || process.cwd();
220
+ const devAccountsDir = path2.join(workspaceRoot, ".hardkas", "dev-accounts");
221
+ if (fs2.existsSync(devAccountsDir)) {
222
+ const files = fs2.readdirSync(devAccountsDir);
223
+ for (const file of files) {
224
+ if (file.endsWith(".json")) {
225
+ try {
226
+ const name = path2.basename(file, ".json");
227
+ const data = fs2.readFileSync(path2.join(devAccountsDir, file), "utf-8");
228
+ const keystore = JSON.parse(data);
229
+ if (keystore.type === "hardkas.encryptedKeystore.v2") {
230
+ accounts.set(name, {
231
+ name,
232
+ kind: "kaspa-private-key",
233
+ address: keystore.payload?.address || keystore.metadata?.address
234
+ });
235
+ }
236
+ } catch (e) {
237
+ }
238
+ }
239
+ }
240
+ }
200
241
  const realStore = loadRealAccountStoreSync();
201
242
  if (realStore) {
202
243
  for (const realAcc of listRealDevAccounts(realStore)) {
@@ -846,7 +887,105 @@ var KeystoreManager = class {
846
887
  }
847
888
  }
848
889
  };
890
+
891
+ // src/dev-accounts.ts
892
+ import fs4 from "fs";
893
+ import path4 from "path";
894
+ import crypto2 from "crypto";
895
+ var DEV_ACCOUNTS_PASSWORD = "hardkas-local-dev";
896
+ var SIMNET_DETERMINISTIC_SEED = "hardkas-deterministic-simnet-seed-v1";
897
+ async function ensureDevAccounts(workspaceDir) {
898
+ const devAccountsDir = path4.join(workspaceDir, ".hardkas", "dev-accounts");
899
+ if (!fs4.existsSync(devAccountsDir)) {
900
+ await fs4.promises.mkdir(devAccountsDir, { recursive: true });
901
+ }
902
+ await getOrCreateDevAccount(workspaceDir, 0, "alice");
903
+ await getOrCreateDevAccount(workspaceDir, 1, "bob");
904
+ }
905
+ async function getOrCreateDevAccount(workspaceDir, index, alias) {
906
+ const devAccountsDir = path4.join(workspaceDir, ".hardkas", "dev-accounts");
907
+ const filePath = path4.join(devAccountsDir, `${alias}.json`);
908
+ if (fs4.existsSync(filePath)) {
909
+ const keystore2 = await KeystoreManager.loadEncryptedKeystore(filePath);
910
+ const unlock = await KeystoreManager.decryptEncryptedKeystore(keystore2, DEV_ACCOUNTS_PASSWORD);
911
+ if (!unlock.success || !unlock.payload) {
912
+ throw new Error(`Failed to decrypt dev account ${alias}. Expected password: ${DEV_ACCOUNTS_PASSWORD}`);
913
+ }
914
+ return {
915
+ address: unlock.payload.address,
916
+ privateKey: unlock.payload.privateKey,
917
+ publicKey: unlock.payload.publicKey
918
+ };
919
+ }
920
+ const seedString = `${SIMNET_DETERMINISTIC_SEED}-${index}`;
921
+ const privateKeyHex = crypto2.createHash("sha256").update(seedString).digest("hex");
922
+ let sdk;
923
+ try {
924
+ sdk = await import("@kaspa/core-lib");
925
+ } catch (e) {
926
+ console.warn(`
927
+ [Warning] Kaspa SDK (@kaspa/core-lib) is not installed in the workspace.
928
+ Could not generate dev account '${alias}'.`);
929
+ return { address: "", privateKey: "", publicKey: "" };
930
+ }
931
+ const privKey = new sdk.PrivateKey(privateKeyHex);
932
+ const pubKey = privKey.toPublicKey();
933
+ const address = pubKey.toAddress("simnet").toString();
934
+ const accountData = {
935
+ address,
936
+ privateKey: privKey.toString(),
937
+ publicKey: pubKey.toString()
938
+ };
939
+ if (!fs4.existsSync(devAccountsDir)) {
940
+ await fs4.promises.mkdir(devAccountsDir, { recursive: true });
941
+ }
942
+ const payload = {
943
+ address: accountData.address,
944
+ privateKey: accountData.privateKey,
945
+ network: "simnet"
946
+ };
947
+ if (accountData.publicKey) {
948
+ payload.publicKey = accountData.publicKey;
949
+ }
950
+ const keystore = await KeystoreManager.createEncryptedKeystore(
951
+ payload,
952
+ DEV_ACCOUNTS_PASSWORD,
953
+ {
954
+ label: alias,
955
+ network: "simnet"
956
+ }
957
+ );
958
+ await KeystoreManager.saveEncryptedKeystore(filePath, keystore);
959
+ return accountData;
960
+ }
961
+ function listDevAccountsSync(workspaceDir) {
962
+ const devAccountsDir = path4.join(workspaceDir, ".hardkas", "dev-accounts");
963
+ if (!fs4.existsSync(devAccountsDir)) {
964
+ return [];
965
+ }
966
+ const accounts = [];
967
+ const files = fs4.readdirSync(devAccountsDir);
968
+ for (const file of files) {
969
+ if (file.endsWith(".json")) {
970
+ const name = path4.basename(file, ".json");
971
+ try {
972
+ const data = fs4.readFileSync(path4.join(devAccountsDir, file), "utf-8");
973
+ const keystore = JSON.parse(data);
974
+ if (keystore.type === "hardkas.encryptedKeystore.v2") {
975
+ accounts.push({
976
+ name,
977
+ address: keystore.metadata?.address || ""
978
+ });
979
+ }
980
+ } catch (e) {
981
+ }
982
+ }
983
+ }
984
+ accounts.sort((a, b) => a.name.localeCompare(b.name));
985
+ return accounts;
986
+ }
849
987
  export {
988
+ DEV_ACCOUNTS_PASSWORD,
850
989
  KaspaSdkKeyGenerator,
851
990
  KaspaSdkRealTxSigner,
852
991
  KaspaWasmPrivateKeySigner,
@@ -860,11 +999,14 @@ export {
860
999
  createEmptyRealAccountStore,
861
1000
  createLocalKaspaWallet,
862
1001
  describeAccount,
1002
+ ensureDevAccounts,
863
1003
  getDefaultRealAccountsPath,
864
1004
  getKaspaSigningBackendStatus,
1005
+ getOrCreateDevAccount,
865
1006
  getRealDevAccount,
866
1007
  getRequiredEnv,
867
1008
  importRealDevAccount,
1009
+ listDevAccountsSync,
868
1010
  listHardkasAccounts,
869
1011
  listRealDevAccounts,
870
1012
  loadKaspaWasm,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/accounts",
3
- "version": "0.7.0-alpha",
3
+ "version": "0.7.1-alpha",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,10 +17,10 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "hash-wasm": "^4.12.0",
20
- "@hardkas/artifacts": "0.7.0-alpha",
21
- "@hardkas/localnet": "0.7.0-alpha",
22
- "@hardkas/config": "0.7.0-alpha",
23
- "@hardkas/core": "0.7.0-alpha"
20
+ "@hardkas/artifacts": "0.7.1-alpha",
21
+ "@hardkas/config": "0.7.1-alpha",
22
+ "@hardkas/localnet": "0.7.1-alpha",
23
+ "@hardkas/core": "0.7.1-alpha"
24
24
  },
25
25
  "devDependencies": {
26
26
  "tsup": "^8.3.5",