Skip to content

Commit

Permalink
feat: encrypt and decrypt keys on storage
Browse files Browse the repository at this point in the history
  • Loading branch information
emjshrx committed Feb 3, 2024
1 parent 3bfaf5b commit 3b6bd91
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
10 changes: 8 additions & 2 deletions src/wallet/db/db.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ export type DbInterface = {
getStatus(): string;
getVersion(): Promise<number>;
setVersion(version: number): Promise<void>;
getMasterKey(): Promise<{ privateKey: Buffer; chaincode: Buffer }>;
setMasterKey(privateKey: Buffer, chaincode: Buffer): Promise<void>;
getEncryptedMasterKey(): Promise<{
encryptedKey: string;
chaincode: Buffer;
}>;
setEncryptedMasterKey(
encryptedKey: string,
chaincode: Buffer,
): Promise<void>;
saveAddress(address: string, path: string): Promise<void>;
getAddress(address: string): Promise<string>;
hasAddress(address: string): Promise<boolean>;
Expand Down
16 changes: 8 additions & 8 deletions src/wallet/db/level/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,24 @@ export class WalletDB implements DbInterface {
await this.db.put(wdb.V, version.toString());
}

public async getMasterKey(): Promise<{
privateKey: Buffer;
public async getEncryptedMasterKey(): Promise<{
encryptedKey: string;
chaincode: Buffer;
}> {
const masterKey = await this.db.get(wdb.M);
const privateKey = Buffer.from(masterKey.slice(0, 64), 'hex');
const chaincode = Buffer.from(masterKey.slice(64), 'hex');
const [chainCodeHex, encryptedKey] = masterKey.split(':');
const chaincode = Buffer.from(chainCodeHex, 'hex');

return { privateKey, chaincode };
return { encryptedKey, chaincode };
}

public async setMasterKey(
privateKey: Buffer,
public async setEncryptedMasterKey(
encryptedKey: string,
chaincode: Buffer,
): Promise<void> {
await this.db.put(
wdb.M,
Buffer.concat([privateKey, chaincode]).toString('hex'),
`${chaincode.toString('hex')}:${encryptedKey}`,
);
}

Expand Down
35 changes: 31 additions & 4 deletions src/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Coin } from './coin.ts';
import { ECPairFactory } from 'ecpair';
import { createOutputs } from '../core';
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371';
import bip38 from 'bip38';

initEccLib(ecc);
const ECPair = ECPairFactory(ecc);
Expand All @@ -27,25 +28,44 @@ export class Wallet {
private masterKey: BIP32Interface;
private receiveDepth: number = 0;
private changeDepth: number = 0;
private encryptionPassword: string = '12345678';
private compressedKey: boolean = true;

constructor(config: WalletConfigOptions) {
this.db = config.db;
this.network = config.networkClient;
}

async init(mnemonic?: string) {
async init(mnemonic?: string, password?: string) {
if (password) {
this.encryptionPassword = password;
}

await this.db.open();

if (mnemonic) {
const seed = mnemonicToSeedSync(mnemonic).toString('hex');
this.masterKey = bip32.fromSeed(Buffer.from(seed, 'hex'));
await this.db.setMasterKey(
const encryptedKey = bip38.encrypt(
this.masterKey.privateKey,
this.compressedKey,
this.encryptionPassword,
);
await this.db.setEncryptedMasterKey(
encryptedKey,
this.masterKey.chainCode,
);
} else {
const { privateKey, chaincode } = await this.db.getMasterKey();
this.masterKey = bip32.fromPrivateKey(privateKey, chaincode);
const { encryptedKey, chaincode } =
await this.db.getEncryptedMasterKey();
const decryptedKey = bip38.decrypt(
encryptedKey,
this.encryptionPassword,
);
this.masterKey = bip32.fromPrivateKey(
decryptedKey.privateKey,
chaincode,
);
}
}

Expand Down Expand Up @@ -258,4 +278,11 @@ export class Wallet {

return tx.getId();
}
setPassword(newPassword: string, oldPassword: string): void {
if (oldPassword !== this.encryptionPassword) {
throw new Error('Wrong old encryption password!');
} else {
this.encryptionPassword = newPassword;
}
}
}

0 comments on commit 3b6bd91

Please sign in to comment.