UNPKG

@dao-xyz/peerbit

Version:

Distributed p2p database on IPFS

103 lines 4.29 kB
import { Ed25519Keypair, Keypair, X25519PublicKey, } from "@dao-xyz/peerbit-crypto"; import { AccessError, X25519Keypair, } from "@dao-xyz/peerbit-crypto"; import { keysPBM } from "@libp2p/crypto/keys"; import { identity } from "multiformats/hashes/identity"; import { base58btc } from "multiformats/bases/base58"; import { Cache } from "@dao-xyz/cache"; import createError from "err-code"; export class FastKeychain { identityKeypair; defaultEncryptionKeypair; keychain; keychainCache = new Cache({ max: 1000 }); constructor(identityKeypair, defaultEncryptionKeypair, keychain) { this.identityKeypair = identityKeypair; this.defaultEncryptionKeypair = defaultEncryptionKeypair; this.keychain = keychain; } static async create(identityKeypair, keychain) { const fk = new FastKeychain(identityKeypair, await X25519Keypair.from(identityKeypair), keychain); // Import peerId to keychain so it can be easily accessible try { await fk.importKeypair(fk.identityKeypair); } catch (error) { if (error.code === "ERR_KEY_ALREADY_EXISTS") { return fk; } throw error; } return fk; } keychainKeyIdFromPublicKey(publicKey) { const bytes = keysPBM.PublicKey.encode({ Type: keysPBM.KeyType.Ed25519, Data: publicKey.publicKey, }).subarray(); const encoding = identity.digest(bytes); return base58btc.encode(encoding.bytes).substring(1); } exportKeypair = async (publicKey) => { /* const id = keychainKeyIdFromPublicKey(publicKey); const key = await keychain.findKeyById(id); const password = "default-password"; const pem = await keychain.exportKey(key.name, password); const privateKey = await importKey(pem, password); return new X25519Keypair({ publicKey: new X25519PublicKey({ publicKey: privateKey.public.bytes }), secretKey: new X25519SecretKey({ secretKey: privateKey.bytes.slice(0, 32), }), }); */ const key = base58btc.encode(publicKey.bytes); const cached = this.keychainCache.get(key); if (cached === null) { throw createError(new Error("Key declared null in cache"), "ERR_NOT_FOUND"); } else if (cached instanceof Keypair) { return cached; } const peerId = await this.keychain.exportPeerId(key); return (publicKey instanceof X25519PublicKey ? X25519Keypair.fromPeerId(peerId) : Ed25519Keypair.fromPeerId(peerId)); }; importKeypair = async (keypair) => { const receiverKeyPeerId = await keypair.toPeerId(); const edKey = base58btc.encode(keypair.publicKey.bytes); const xKeypair = await X25519Keypair.from(keypair); const xKey = base58btc.encode(xKeypair.publicKey.bytes); this.keychainCache.add(edKey, xKeypair); this.keychainCache.add(xKey, xKeypair); // import as ed await this.keychain.importPeer(edKey, receiverKeyPeerId); // import as x so we can decrypt messages with this public key (if recieved any) await this.keychain.importPeer(xKey, receiverKeyPeerId); }; // Arrow function is used so we can reference this function and use 'this' without .bind(self) getAnyKeypair = async (publicKeys) => { for (let i = 0; i < publicKeys.length; i++) { try { const key = await this.exportKeypair(publicKeys[i]); if (key && key instanceof X25519Keypair) { return { index: i, keypair: key, }; } } catch (error) { // Key missing if (error.code !== "ERR_NOT_FOUND") { throw error; } } } throw new AccessError("Failed to access key"); }; // Arrow function is used so we can reference this function and use 'this' without .bind(self) getEncryptionKeypair = () => { return this.defaultEncryptionKeypair; }; } //# sourceMappingURL=encryption.js.map