Simplify exports
This commit is contained in:
parent
501f93e333
commit
269c96832b
38
README.md
38
README.md
|
@ -19,10 +19,10 @@ To use native bindings you must install peer dependency `@chainsafe/blst`
|
|||
yarn add @chainsafe/bls @chainsafe/blst
|
||||
```
|
||||
|
||||
You must initialize the library once in your application before using it. The result is cached and use across all your imports
|
||||
By default, native bindings will be used if in NodeJS and they are installed. A WASM implementation ("herumi") is used as a fallback in case any error occurs.
|
||||
|
||||
```ts
|
||||
import {init, SecretKey, secretKeyToPublicKey, sign, verify} from "@chainsafe/bls";
|
||||
import {SecretKey, secretKeyToPublicKey, sign, verify} from "@chainsafe/bls";
|
||||
|
||||
(async () => {
|
||||
await init("herumi");
|
||||
|
@ -45,7 +45,7 @@ import {init, SecretKey, secretKeyToPublicKey, sign, verify} from "@chainsafe/bl
|
|||
|
||||
### Browser
|
||||
|
||||
If you are in the browser, import from `/herumi` to import directly the WASM version
|
||||
If you are in the browser, import from `/herumi` to explicitly import the WASM version
|
||||
|
||||
```ts
|
||||
import bls from "@chainsafe/bls/herumi";
|
||||
|
@ -53,7 +53,7 @@ import bls from "@chainsafe/bls/herumi";
|
|||
|
||||
### Native bindings only
|
||||
|
||||
If you are in NodeJS, import from `/blst-native` to skip browser specific code. Also install peer dependency `@chainsafe/blst` which has the native bindings
|
||||
If you are in NodeJS, import from `/blst-native` to explicitly import the native bindings. Also install peer dependency `@chainsafe/blst` which has the native bindings
|
||||
|
||||
```bash
|
||||
yarn add @chainsafe/bls @chainsafe/blst
|
||||
|
@ -63,23 +63,27 @@ yarn add @chainsafe/bls @chainsafe/blst
|
|||
import bls from "@chainsafe/bls/blst-native";
|
||||
```
|
||||
|
||||
### Native bindings + WASM fallback
|
||||
### Get implementation at runtime
|
||||
|
||||
If you want to offer a fallback in NodeJS, first try to load native bindings and then fallback to WASM. Also install peer dependency `@chainsafe/blst` which has the native bindings
|
||||
|
||||
```bash
|
||||
yarn add @chainsafe/bls @chainsafe/blst
|
||||
```
|
||||
If you need to get a bls implementation at runtime, import from `/getImplementation`.
|
||||
|
||||
```ts
|
||||
import {init} from "@chainsafe/bls";
|
||||
import {getImplementation} from "@chainsafe/bls/getImplementation";
|
||||
|
||||
try {
|
||||
await init("blst-native");
|
||||
} catch (e) {
|
||||
await init("herumi");
|
||||
console.warn("Using WASM");
|
||||
}
|
||||
const bls = await getImplementation("herumi");
|
||||
```
|
||||
|
||||
### Switchable singleton
|
||||
|
||||
If you need a singleton that is switchable at runtime (the default behavior in <=v6), import from `/switchable`.
|
||||
|
||||
```ts
|
||||
import bls, {init} from "@chainsafe/bls/switchable";
|
||||
|
||||
// here `bls` is uninitialized
|
||||
await init("herumi");
|
||||
// here `bls` is initialized
|
||||
// now other modules can `import bls from "@chainsafe/bls/switchable"` and it will be initialized
|
||||
```
|
||||
|
||||
The API is identical for all implementations.
|
||||
|
|
10
package.json
10
package.json
|
@ -7,14 +7,14 @@
|
|||
".": {
|
||||
"import": "./lib/index.js"
|
||||
},
|
||||
"./register": {
|
||||
"import": "./register.js"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./lib/types.js"
|
||||
},
|
||||
"./default": {
|
||||
"import": "./lib/default.js"
|
||||
"./getImplementation": {
|
||||
"import": "./lib/getImplementation.js"
|
||||
},
|
||||
"./switchable": {
|
||||
"import": "./lib/switchable.js"
|
||||
},
|
||||
"./blst-native": {
|
||||
"import": "./lib/blst-native/index.js"
|
||||
|
|
12
register.js
12
register.js
|
@ -1,12 +0,0 @@
|
|||
// -----------------------------------------
|
||||
// To be used in NodeJS testing environments
|
||||
// node -r @chainsafe/bls/register
|
||||
// -----------------------------------------
|
||||
|
||||
// blst-native initialization is syncronous
|
||||
// Initialize bls here instead of in before() so it's available inside describe() blocks
|
||||
import("./lib/index.js").then(({init}) => init("blst-native")).catch((e) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
|
@ -7,13 +7,6 @@ export * from "../constants.js";
|
|||
|
||||
export {SecretKey, PublicKey, Signature};
|
||||
|
||||
export async function init(): Promise<void> {
|
||||
// Native bindings require no init() call
|
||||
}
|
||||
export function destroy(): void {
|
||||
// Native bindings require no destroy() call
|
||||
}
|
||||
|
||||
export const bls: IBls = {
|
||||
implementation: "blst-native",
|
||||
SecretKey,
|
||||
|
@ -21,8 +14,6 @@ export const bls: IBls = {
|
|||
Signature,
|
||||
|
||||
...functionalInterfaceFactory({SecretKey, PublicKey, Signature}),
|
||||
init,
|
||||
destroy,
|
||||
};
|
||||
|
||||
export default bls;
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import type {IBls} from "./interface.js";
|
||||
import {getImplementation} from "./getImplementation.js";
|
||||
|
||||
// Thanks https://github.com/iliakan/detect-node/blob/master/index.esm.js
|
||||
const isNode = Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]";
|
||||
|
||||
let bls: IBls;
|
||||
try {
|
||||
bls = await getImplementation(isNode ? "blst-native" : "herumi");
|
||||
} catch (e) {
|
||||
bls = await getImplementation("herumi");
|
||||
}
|
||||
|
||||
export default bls;
|
|
@ -6,9 +6,7 @@ const isNode = Object.prototype.toString.call(typeof process !== "undefined" ? p
|
|||
export async function getImplementation(impl: Implementation = "herumi"): Promise<IBls> {
|
||||
switch (impl) {
|
||||
case "herumi": {
|
||||
const blsHerumi = (await import("./herumi/index.js")).bls;
|
||||
await blsHerumi.init();
|
||||
return blsHerumi;
|
||||
return (await import("./herumi/index.js")).bls;
|
||||
}
|
||||
|
||||
case "blst-native":
|
||||
|
|
|
@ -4,6 +4,9 @@ import {Signature} from "./signature.js";
|
|||
import {init, destroy} from "./context.js";
|
||||
import {IBls} from "../interface.js";
|
||||
import {functionalInterfaceFactory} from "../functional.js";
|
||||
|
||||
await init();
|
||||
|
||||
export * from "../constants.js";
|
||||
|
||||
export {SecretKey, PublicKey, Signature, init, destroy};
|
||||
|
@ -15,8 +18,6 @@ export const bls: IBls = {
|
|||
Signature,
|
||||
|
||||
...functionalInterfaceFactory({SecretKey, PublicKey, Signature}),
|
||||
init,
|
||||
destroy,
|
||||
};
|
||||
|
||||
export default bls;
|
||||
|
|
22
src/index.ts
22
src/index.ts
|
@ -1,16 +1,14 @@
|
|||
import type {IBls, Implementation} from "./interface.js";
|
||||
import type {IBls} from "./interface.js";
|
||||
import {getImplementation} from "./getImplementation.js";
|
||||
|
||||
export {IBls, Implementation, CoordType, PointFormat} from "./interface.js";
|
||||
// Thanks https://github.com/iliakan/detect-node/blob/master/index.esm.js
|
||||
const isNode = Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]";
|
||||
|
||||
// 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;
|
||||
|
||||
export async function init(impl: Implementation): Promise<void> {
|
||||
// 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()
|
||||
const blsImpl = await getImplementation(impl);
|
||||
Object.assign(bls, blsImpl);
|
||||
let bls: IBls;
|
||||
try {
|
||||
bls = await getImplementation(isNode ? "blst-native" : "herumi");
|
||||
} catch (e) {
|
||||
bls = await getImplementation("herumi");
|
||||
}
|
||||
|
||||
export default bls;
|
||||
|
|
|
@ -12,9 +12,6 @@ export interface IBls {
|
|||
verifyMultiple(publicKeys: Uint8Array[], messages: Uint8Array[], signature: Uint8Array): boolean;
|
||||
verifyMultipleSignatures(sets: {publicKey: Uint8Array; message: Uint8Array; signature: Uint8Array}[]): boolean;
|
||||
secretKeyToPublicKey(secretKey: Uint8Array): Uint8Array;
|
||||
|
||||
init(): Promise<void>;
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export declare class SecretKey {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import type {IBls, Implementation} from "./interface.js";
|
||||
import {getImplementation} from "./getImplementation.js";
|
||||
|
||||
export * from "./interface.js";
|
||||
|
||||
// TODO: Use a Proxy for example to throw an error if it's not initialized yet
|
||||
const bls: IBls = {} as IBls;
|
||||
export default bls;
|
||||
|
||||
export async function init(impl: Implementation): Promise<void> {
|
||||
// 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()
|
||||
const blsImpl = await getImplementation(impl);
|
||||
Object.assign(bls, blsImpl);
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"target": "es2019",
|
||||
"module": "es2022",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "Node",
|
||||
"pretty": true,
|
||||
"lib": ["esnext.bigint", "DOM"],
|
||||
|
|
Reference in New Issue