@hardkas/accounts 0.7.0-alpha → 0.7.3-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 +9 -1
- package/dist/index.js +152 -6
- package/package.json +5 -5
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
|
-
|
|
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
|
-
|
|
160
|
-
|
|
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:
|
|
181
|
+
name: alias,
|
|
163
182
|
...accConfig
|
|
164
183
|
};
|
|
165
184
|
}
|
|
166
185
|
const realStore = loadRealAccountStoreSync();
|
|
167
|
-
const realAcc = realStore ? getRealDevAccount(realStore,
|
|
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 ===
|
|
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)) {
|
|
@@ -563,7 +604,7 @@ var KaspaSdkKeyGenerator = class {
|
|
|
563
604
|
return await rawLoader();
|
|
564
605
|
} catch (e) {
|
|
565
606
|
throw new Error(
|
|
566
|
-
"Kaspa
|
|
607
|
+
"Kaspa cryptography adapter missing. Real account generation requires WASM execution.\nRun: npm install @kaspa/wallet-wasm\nUse 'hardkas accounts real import' to add accounts manually for now."
|
|
567
608
|
);
|
|
568
609
|
}
|
|
569
610
|
};
|
|
@@ -846,7 +887,109 @@ 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 sdkModule;
|
|
923
|
+
try {
|
|
924
|
+
sdkModule = await import(
|
|
925
|
+
/* @vite-ignore */
|
|
926
|
+
"@kaspa/core-lib"
|
|
927
|
+
);
|
|
928
|
+
} catch (e) {
|
|
929
|
+
console.warn(`
|
|
930
|
+
[Warning] Kaspa SDK (@kaspa/core-lib) is not installed in the workspace.
|
|
931
|
+
Could not generate dev account '${alias}'.`);
|
|
932
|
+
return { address: "", privateKey: "", publicKey: "" };
|
|
933
|
+
}
|
|
934
|
+
const sdk = sdkModule.default || sdkModule;
|
|
935
|
+
const privKey = new sdk.PrivateKey(privateKeyHex);
|
|
936
|
+
const pubKey = privKey.toPublicKey();
|
|
937
|
+
const address = pubKey.toAddress("simnet").toString();
|
|
938
|
+
const accountData = {
|
|
939
|
+
address,
|
|
940
|
+
privateKey: privKey.toString(),
|
|
941
|
+
publicKey: pubKey.toString()
|
|
942
|
+
};
|
|
943
|
+
if (!fs4.existsSync(devAccountsDir)) {
|
|
944
|
+
await fs4.promises.mkdir(devAccountsDir, { recursive: true });
|
|
945
|
+
}
|
|
946
|
+
const payload = {
|
|
947
|
+
address: accountData.address,
|
|
948
|
+
privateKey: accountData.privateKey,
|
|
949
|
+
network: "simnet"
|
|
950
|
+
};
|
|
951
|
+
if (accountData.publicKey) {
|
|
952
|
+
payload.publicKey = accountData.publicKey;
|
|
953
|
+
}
|
|
954
|
+
const keystore = await KeystoreManager.createEncryptedKeystore(
|
|
955
|
+
payload,
|
|
956
|
+
DEV_ACCOUNTS_PASSWORD,
|
|
957
|
+
{
|
|
958
|
+
label: alias,
|
|
959
|
+
network: "simnet"
|
|
960
|
+
}
|
|
961
|
+
);
|
|
962
|
+
await KeystoreManager.saveEncryptedKeystore(filePath, keystore);
|
|
963
|
+
return accountData;
|
|
964
|
+
}
|
|
965
|
+
function listDevAccountsSync(workspaceDir) {
|
|
966
|
+
const devAccountsDir = path4.join(workspaceDir, ".hardkas", "dev-accounts");
|
|
967
|
+
if (!fs4.existsSync(devAccountsDir)) {
|
|
968
|
+
return [];
|
|
969
|
+
}
|
|
970
|
+
const accounts = [];
|
|
971
|
+
const files = fs4.readdirSync(devAccountsDir);
|
|
972
|
+
for (const file of files) {
|
|
973
|
+
if (file.endsWith(".json")) {
|
|
974
|
+
const name = path4.basename(file, ".json");
|
|
975
|
+
try {
|
|
976
|
+
const data = fs4.readFileSync(path4.join(devAccountsDir, file), "utf-8");
|
|
977
|
+
const keystore = JSON.parse(data);
|
|
978
|
+
if (keystore.type === "hardkas.encryptedKeystore.v2") {
|
|
979
|
+
accounts.push({
|
|
980
|
+
name,
|
|
981
|
+
address: keystore.metadata?.address || ""
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
} catch (e) {
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
accounts.sort((a, b) => a.name.localeCompare(b.name));
|
|
989
|
+
return accounts;
|
|
990
|
+
}
|
|
849
991
|
export {
|
|
992
|
+
DEV_ACCOUNTS_PASSWORD,
|
|
850
993
|
KaspaSdkKeyGenerator,
|
|
851
994
|
KaspaSdkRealTxSigner,
|
|
852
995
|
KaspaWasmPrivateKeySigner,
|
|
@@ -860,11 +1003,14 @@ export {
|
|
|
860
1003
|
createEmptyRealAccountStore,
|
|
861
1004
|
createLocalKaspaWallet,
|
|
862
1005
|
describeAccount,
|
|
1006
|
+
ensureDevAccounts,
|
|
863
1007
|
getDefaultRealAccountsPath,
|
|
864
1008
|
getKaspaSigningBackendStatus,
|
|
1009
|
+
getOrCreateDevAccount,
|
|
865
1010
|
getRealDevAccount,
|
|
866
1011
|
getRequiredEnv,
|
|
867
1012
|
importRealDevAccount,
|
|
1013
|
+
listDevAccountsSync,
|
|
868
1014
|
listHardkasAccounts,
|
|
869
1015
|
listRealDevAccounts,
|
|
870
1016
|
loadKaspaWasm,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/accounts",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-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.
|
|
21
|
-
"@hardkas/
|
|
22
|
-
"@hardkas/config": "0.7.
|
|
23
|
-
"@hardkas/
|
|
20
|
+
"@hardkas/artifacts": "0.7.3-alpha",
|
|
21
|
+
"@hardkas/core": "0.7.3-alpha",
|
|
22
|
+
"@hardkas/config": "0.7.3-alpha",
|
|
23
|
+
"@hardkas/localnet": "0.7.3-alpha"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"tsup": "^8.3.5",
|