diff --git a/karma.conf.js b/karma.conf.js index 4599b2a..1423525 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -6,7 +6,7 @@ module.exports = function(config) { basePath: "", frameworks: ["mocha", "chai"], - files: ["test/unit/run-web-implementation.test.ts"], + files: ["test/unit/run-web-implementation.test.ts", "test/unit/index-named-exports.test.ts"], exclude: [], preprocessors: { "test/**/*.ts": ["webpack"] @@ -23,4 +23,4 @@ module.exports = function(config) { singleRun: true }); -}; \ No newline at end of file +}; diff --git a/src/index.ts b/src/index.ts index bcf1267..cad6199 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import {IBls} from "./interface"; +import {IBls, IPrivateKey, IPublicKey, ISignature} from "./interface"; import {bls as blsHerumi} from "./herumi"; export type Implementation = "herumi" | "blst-native"; @@ -7,6 +7,7 @@ export * from "./interface"; // TODO: Use a Proxy for example to throw an error if it's not initialized yet export const bls: IBls = {} as IBls; +export default bls; async function getImplementation(impl: Implementation = "herumi"): Promise { switch (impl) { @@ -31,7 +32,44 @@ export async function init(impl: Implementation): Promise { // Using Object.assign instead of just bls = getImplementation() // because otherwise the default import breaks. The reference is lost // and the imported object is still undefined after calling init() - Object.assign(bls, await getImplementation(impl)); + const blsImpl = await getImplementation(impl); + Object.assign(bls, blsImpl); + Object.assign(exports, blsImpl); } -export default bls; +// Proxy named exports, will get set by `Object.assign(exports, blsImpl)` +export declare let sign: IBls["sign"]; +export declare let aggregateSignatures: IBls["aggregateSignatures"]; +export declare let aggregatePubkeys: IBls["aggregatePubkeys"]; +export declare let verify: IBls["verify"]; +export declare let verifyAggregate: IBls["verifyAggregate"]; +export declare let verifyMultiple: IBls["verifyMultiple"]; + +export declare class PrivateKey implements IPrivateKey { + static fromBytes(bytes: Uint8Array): PrivateKey; + static fromHex(hex: string): PrivateKey; + static fromKeygen(entropy?: Uint8Array): PrivateKey; + sign(message: Uint8Array): Signature; + toPublicKey(): PublicKey; + toBytes(): Uint8Array; + toHex(): string; +} + +export declare class PublicKey implements IPublicKey { + static fromBytes(bytes: Uint8Array): PublicKey; + static fromHex(hex: string): PublicKey; + static aggregate(pubkeys: PublicKey[]): PublicKey; + toBytes(): Uint8Array; + toHex(): string; +} + +export declare class Signature implements ISignature { + static fromBytes(bytes: Uint8Array): Signature; + static fromHex(hex: string): Signature; + static aggregate(signatures: Signature[]): Signature; + verify(publicKey: PublicKey, message: Uint8Array): boolean; + verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean; + verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean; + toBytes(): Uint8Array; + toHex(): string; +} diff --git a/test/unit/helpers/bytes.test.ts b/test/unit/helpers/bytes.test.ts index 1958185..2b14df7 100644 --- a/test/unit/helpers/bytes.test.ts +++ b/test/unit/helpers/bytes.test.ts @@ -17,7 +17,6 @@ describe("helpers / bytes", () => { for (const {hex, isZero} of testCases) { it(`${hex} isZero = ${isZero}`, () => { const bytes = hexToBytesNode(hex); - console.log(bytes); expect(isZeroUint8Array(bytes)).to.equal(isZero); }); } diff --git a/test/unit/index-named-exports.test.ts b/test/unit/index-named-exports.test.ts new file mode 100644 index 0000000..e383ebf --- /dev/null +++ b/test/unit/index-named-exports.test.ts @@ -0,0 +1,21 @@ +import {expect} from "chai"; +import {PrivateKey, PublicKey, Signature, init} from "../../src"; + +describe("index named exports", () => { + it("Classes and methods should be defined", async () => { + await init("herumi"); + + const sk = PrivateKey.fromKeygen(); + const msg = new Uint8Array(32); + const sig = sk.sign(msg); + const pk = sk.toPublicKey(); + expect(verifyHelper(pk, sig, msg)).to.be.true; + }); + + /** + * Sample helper to test argument typing + */ + function verifyHelper(pk: PublicKey, sig: Signature, msg: Uint8Array): boolean { + return sig.verify(pk, msg); + } +});