UNPKG

@bajetech/digitalbits-wallet-sdk

Version:

A library to make it easier to write wallets that interact with the DigitalBits blockchain

191 lines (151 loc) 4.75 kB
import DigitalBitsSdk from "xdb-digitalbits-sdk"; import { KeyType } from "./constants/keys"; import { generateEncryptedKey } from "./fixtures/keys"; import { getKeyMetadata } from "./helpers/getKeyMetadata"; import { EncryptedKey, Encrypter, Key, KeyMetadata, KeyStore } from "./types"; function isKey(obj: any): obj is Key { return obj.privateKey !== undefined; } function isEncryptedKey(obj: any): obj is EncryptedKey { return obj.encryptedBlob !== undefined; } /** * Validates an `Encrypter` object. Resolves to true if valid. */ export async function testEncrypter(encrypter: any = 0): Promise<boolean> { const account = DigitalBitsSdk.Keypair.random(); if (!encrypter) { return Promise.reject(new Error("[Encrypter] Encrypter not defined")); } if (typeof encrypter.name !== "string") { return Promise.reject(new Error("[Encrypter.name] Name not defined")); } if (typeof encrypter.encryptKey !== "function") { return Promise.reject( new Error("[Encrypter.encryptKey] Function not found") ); } if (typeof encrypter.decryptKey !== "function") { return Promise.reject( new Error("[Encrypter.decryptKey] Function not found") ); } const publicKey = account.publicKey(); const privateKey = account.secret(); const key: Key = { id: "test id", type: KeyType.plaintextKey, publicKey, privateKey, }; const password = "kh2fu0b939uvdkj"; const encryptedKey = await (encrypter as Encrypter).encryptKey({ key, password, }); if (!isEncryptedKey(encryptedKey)) { return Promise.reject( new Error("[Encrypter.encryptKey] Encrypted key not valid") ); } const decryptedKey = await (encrypter as Encrypter).decryptKey({ encryptedKey, password, }); if (!isKey(decryptedKey)) { return Promise.reject( new Error("[Encrypter.decryptKey] Decrypted key not valid") ); } if (decryptedKey.privateKey !== key.privateKey) { return Promise.reject( new Error( "[Encrypter.decryptKey] Decrypted key doesn't match original key" ) ); } return Promise.resolve(true); } /** * Validates a `KeyStore` object. Resolves to true if valid. */ export async function testKeyStore( keyStoreCandidate: any = null ): Promise<boolean> { if (!keyStoreCandidate) { return Promise.reject(new Error("[KeyStore] KeyStore not defined")); } if (!keyStoreCandidate.name) { return Promise.reject(new Error("[KeyStore.name] Name not defined")); } const functions = [ "configure", "storeKeys", "updateKeys", "loadKey", "removeKey", "loadAllKeys", ]; for (const functionName of functions) { if (typeof keyStoreCandidate[functionName] !== "function") { return Promise.reject( new Error(`[KeyStore.${functionName}] Invalid function`) ); } } const keyStore: KeyStore = keyStoreCandidate as KeyStore; const encryptedKey: EncryptedKey = generateEncryptedKey(keyStore.name); const keyMetadata: KeyMetadata = getKeyMetadata(encryptedKey); // make sure we can't update a key that doesn't exist try { await keyStore.updateKeys([encryptedKey]); return Promise.reject( new Error( "[KeyStore.updateKeys] Doesn't error when updating a nonexistent key" ) ); } catch (e) { // good! } // KeyStore.storeKeys const testMetadata = await keyStore.storeKeys([encryptedKey]); if (keyMetadata.id !== (testMetadata[0] as KeyMetadata).id) { return Promise.reject( new Error("[KeyStore.storeKeys] Key metadata doesn't match") ); } try { await keyStore.storeKeys([encryptedKey]); return Promise.reject( new Error("[KeyStore.updateKeys] Doesn't error when storing a stored key") ); } catch (e) { // good! } // make sure we can't store a key that exists const allKeys = await keyStore.loadAllKeys(); if ( allKeys.length !== 1 || encryptedKey.encryptedBlob !== (allKeys[0] as EncryptedKey).encryptedBlob ) { return Promise.reject( new Error("[KeyStore.loadAllKeys] loadAllKeys doesn't match") ); } const removalMetadata = await keyStore.removeKey(encryptedKey.id); if (!removalMetadata || keyMetadata.id !== removalMetadata.id) { return Promise.reject( new Error("[KeyStore.removeKey] Removed metadata doesn't match") ); } if (!removalMetadata || keyMetadata.id !== removalMetadata.id) { return Promise.reject( new Error("[KeyStore.removeKey] Removed metadata doesn't match") ); } const noKeys = await keyStore.loadAllKeys(); if (noKeys.length) { return Promise.reject(new Error("[KeyStore.removeKey] Key not removed")); } return Promise.resolve(true); }