UNPKG

@chorus-one/signer-local

Version:

Local signer for Chorus One SDK that utilizes a BIP39 mnemonic for signing operations

130 lines (129 loc) 5.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LocalSigner = void 0; const signer_1 = require("@chorus-one/signer"); const utils_1 = require("@chorus-one/utils"); const bip39_1 = require("bip39"); const ed25519_1 = require("./ed25519"); const secp256k1_1 = require("./secp256k1"); /** * The LocalSigner in the Chorus One SDK is a specialized implementation of the Signer interface that utilizes a `BIP39` * mnemonic for signing operations. * * This signer is ideal for local environments where you need a straightforward and * secure method to generate and manage cryptographic keys from mnemonic phrases. */ class LocalSigner { config; accounts; addressDerivationFn; mnemonicToSeedFn; seedToKeypairFn; logger; /** * Constructs a new LocalSigner. * * @param params - The parameters required to initialize the LocalSigner * @param params.mnemonic - A string containing your `BIP39` mnemonic phrase * @param params.keyType - An enum specifying the signing key type (e.g. SECP256K1, ED25519) * @param params.accounts - An array of account objects, each containing an HD path * @param params.addressDerivationFn - A function that derives the address from the public key * @param params.logger - (Optional) A logger to use for logging messages, i.e `console` * * @returns A new instance of LocalSigner. */ constructor(params) { const { addressDerivationFn, ...config } = params; this.config = config; this.accounts = new Map(); this.logger = params.logger ?? utils_1.nopLogger; this.addressDerivationFn = addressDerivationFn; this.mnemonicToSeedFn = params.mnemonicToSeedFn ?? bip39_1.mnemonicToSeed; this.seedToKeypairFn = params.seedToKeypairFn; } /** * Initializes the signer, performing any necessary setup or configuration. * @returns A promise that resolves once the initialization is complete. */ async init() { const seed = await this.mnemonicToSeedFn(this.config.mnemonic); await Promise.all(this.config.accounts.map(async (account) => { let key; switch (this.config.keyType) { case undefined: case signer_1.KeyType.SECP256K1: { const fn = this.seedToKeypairFn ?? secp256k1_1.deriveKey; key = await fn(seed, account.hdPath); break; } case signer_1.KeyType.ED25519: { const fn = this.seedToKeypairFn ?? ed25519_1.deriveKey; key = await fn(seed, account.hdPath); break; } default: throw new Error('unsupported key type'); } const publicKey = key.publicKey; const privateKey = key.privateKey; const derivedAddresses = await this.addressDerivationFn(key.publicKey, account.hdPath); derivedAddresses.forEach((address) => { this.accounts.set(address.toLowerCase(), { hdPath: account.hdPath, privateKey, publicKey }); }); })); } /** * Signs the provided data using the private key associated with the signer's address. * * @param signerAddress - The address of the signer * @param signerData - The data to be signed, which can be a raw message or custom data * * @returns A promise that resolves to an object containing the signature and public key. */ async sign(signerAddress, signerData) { this.logger.info(`signing data from address: ${signerAddress}`); if (signerData.message === undefined) { throw new Error('missing message to sign'); } const content = signerData.message; let sig; switch (this.config.keyType) { case undefined: case signer_1.KeyType.SECP256K1: sig = await (0, secp256k1_1.sign)(content, this.getPrivateKey(signerAddress)); break; case signer_1.KeyType.ED25519: sig = await (0, ed25519_1.sign)(content, this.getPrivateKey(signerAddress)); break; default: throw new Error('unsupported key type'); } return { sig, pk: await this.getPublicKey(signerAddress) }; } /** * Retrieves the public key associated with the signer's address. * * @param address - The address of the signer * * @returns A promise that resolves to a Uint8Array representing the public key. */ async getPublicKey(address) { const account = this.accounts.get(address.toLowerCase()); if (account === undefined) { throw new Error(`no public key found for address: ${address}`); } return account.publicKey; } getPrivateKey(address) { const account = this.accounts.get(address.toLowerCase()); if (account === undefined) { throw new Error(`no private key found for address: ${address}`); } return account.privateKey; } } exports.LocalSigner = LocalSigner;