create daemon
This commit is contained in:
91
thrower_daemon/node_modules/nostr-wasm/README.md
generated
vendored
Normal file
91
thrower_daemon/node_modules/nostr-wasm/README.md
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
# nostr-wasm
|
||||
|
||||
Nostr signature stuff in WASM based on libsecp256k1.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Demo
|
||||
|
||||
A demo application using this package is available at https://nostr-wasm-demo.pages.dev/.
|
||||
|
||||
## Usage
|
||||
|
||||
First, choose which import method suites your needs:
|
||||
|
||||
#### Default
|
||||
|
||||
Import with the WASM binary preloaded and uncompressed. No need to perform `fetch`, but bundle will be larger (+332 KiB).
|
||||
|
||||
```ts
|
||||
import {initNostrWasm} from 'nostr-wasm'
|
||||
const nw = await initNostrWasm()
|
||||
```
|
||||
|
||||
#### Compressed
|
||||
|
||||
Import with the WASM binary preloaded and gzipped (requires access to `globalThis.DecompressionSteam`). No need to perform `fetch`, but bundle will be still be a bit larger (+175 KiB).
|
||||
|
||||
```ts
|
||||
import {initNostrWasm} from 'nostr-wasm/gzipped'
|
||||
const nw = await initNostrWasm()
|
||||
```
|
||||
|
||||
#### Headless
|
||||
|
||||
Import without the WASM binary. Produces the smallest bundle size but requires fetching the binary yourself.
|
||||
|
||||
```ts
|
||||
import {NostrWasm} from 'nostr-wasm/headless'
|
||||
|
||||
// provide the binary (the constructor also accepts raw bytes)
|
||||
const nw = await NostrWasm(await fetch('secp256k1.wasm'))
|
||||
```
|
||||
|
||||
### Using the instance:
|
||||
|
||||
```ts
|
||||
// generate a random private key
|
||||
const sec = nw.generateSecretKey()
|
||||
|
||||
// get its corresponding public key
|
||||
const pubkey = nw.getPublicKey(sec)
|
||||
|
||||
// finalize a nostr event in-place, filling it with id, pubkey and sig
|
||||
nw.finalizeEvent(event, sec)
|
||||
|
||||
// verify a nostr event checking its id and its signature against the given pubkey
|
||||
try {
|
||||
nw.verifyEvent(event)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
```
|
||||
|
||||
Caller is responsible for zero-ing out private keys in the Uint8Array it passes. Library only zeroes out the bytes in the copies it makes.
|
||||
|
||||
## Is libsecp256k1 modified?
|
||||
|
||||
No, the library is imported as a git submodule directly from upstream.
|
||||
|
||||
## Building from source
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- [Podman](https://podman.io/)
|
||||
- [Bun](https://bun.sh/)
|
||||
- [Just](https://just.systems/)
|
||||
|
||||
```sh
|
||||
git clone --recurse-submodules https://github.com/fiatjaf/nostr-wasm
|
||||
cd nostr-wasm
|
||||
bun install
|
||||
just
|
||||
```
|
||||
|
||||
The WASM binary will be output to `public/out/secp256k1.wasm`.
|
||||
|
||||
The Emscripten-generated js file at `public/out/secp256k1.js` is not needed for production if you are using the provided wrapper.
|
||||
3
thrower_daemon/node_modules/nostr-wasm/dist/api/emsimp.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/nostr-wasm/dist/api/emsimp.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/// <reference types="web" />
|
||||
import type { ImportMapper } from 'src/types';
|
||||
export declare const emsimp: (f_map_imports: ImportMapper, label: string) => readonly [WebAssembly.Imports, (d_memory: WebAssembly.Memory) => readonly [ArrayBuffer, Uint8Array, Uint32Array]];
|
||||
45
thrower_daemon/node_modules/nostr-wasm/dist/api/nostr.d.ts
generated
vendored
Normal file
45
thrower_daemon/node_modules/nostr-wasm/dist/api/nostr.d.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/// <reference types="web" />
|
||||
/// <reference types="node" />
|
||||
type Event = {
|
||||
id: string;
|
||||
pubkey: string;
|
||||
sig: string;
|
||||
content: string;
|
||||
kind: number;
|
||||
created_at: number;
|
||||
tags: string[][];
|
||||
};
|
||||
export interface Nostr {
|
||||
/**
|
||||
* Generates a new private key using crypto secure random bytes and without modulo bias
|
||||
* @returns a new private key (32 bytes)
|
||||
*/
|
||||
generateSecretKey(): Uint8Array;
|
||||
/**
|
||||
* Computes the public key for a given private key
|
||||
* @param seckey - the private key (32 bytes)
|
||||
* @returns the public key (32 bytes)
|
||||
*/
|
||||
getPublicKey(seckey: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* Fills in an event object with pubkey, id and sig.
|
||||
* @param event - the Nostr event object
|
||||
* @param seckey - the private key
|
||||
* @param entropy - optional entropy to use
|
||||
*/
|
||||
finalizeEvent(event: Event, seckey: Uint8Array, ent?: Uint8Array): void;
|
||||
/**
|
||||
* Verifies if an event's .id property is correct and that the .sig is valid
|
||||
* @param event - the Nostr event object
|
||||
* @throws an error with a .message if the event is not valid for any reason
|
||||
*/
|
||||
verifyEvent(event: Event): void;
|
||||
}
|
||||
/**
|
||||
* Creates a new instance of the secp256k1 WASM and returns the Nostr wrapper
|
||||
* @param z_src - a Response containing the WASM binary, a Promise that resolves to one,
|
||||
* or the raw bytes to the WASM binary as a {@link BufferSource}
|
||||
* @returns the wrapper API
|
||||
*/
|
||||
export declare const NostrWasm: (z_src: Promise<Response> | Response | BufferSource) => Promise<Nostr>;
|
||||
export {};
|
||||
124
thrower_daemon/node_modules/nostr-wasm/dist/api/secp256k1-types.d.ts
generated
vendored
Normal file
124
thrower_daemon/node_modules/nostr-wasm/dist/api/secp256k1-types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
import type { WasmExportsExtension } from '../gen/wasm.js';
|
||||
import type { Pointer } from '../types.js';
|
||||
export type PointerContext = Pointer<'context'>;
|
||||
export type PointerSeed = Pointer<'seed'>;
|
||||
export type PointerXOnlyKey = Pointer<'xonly_key'>;
|
||||
export type PointerKeypair = Pointer<'keypair'>;
|
||||
export type PointerSig = Pointer<'signature'>;
|
||||
export type PointerSha256 = Pointer<'sha256'>;
|
||||
export declare const enum ByteLens {
|
||||
PRIVATE_KEY = 32,
|
||||
KEYPAIR_LIB = 96,
|
||||
XONLY_KEY_LIB = 64,
|
||||
BIP340_SIG = 64,// secp256k1_bip340_signature: char [64];
|
||||
XONLY_PUBKEY = 32,// serialized
|
||||
MSG_HASH = 32,
|
||||
NONCE_ENTROPY = 32,
|
||||
SHA256_LIB = 104
|
||||
}
|
||||
export declare const enum Flags {
|
||||
CONTEXT_NONE = 1,
|
||||
CONTEXT_VERIFY = 257,
|
||||
CONTEXT_SIGN = 513,
|
||||
CONTEXT_DECLASSIFY = 1025
|
||||
}
|
||||
export declare const enum BinaryResult {
|
||||
SUCCESS = 1,
|
||||
FAILURE = 0
|
||||
}
|
||||
export interface Secp256k1WasmCore extends WasmExportsExtension {
|
||||
/** Create a secp256k1 context object (in dynamically allocated memory).
|
||||
*
|
||||
* This function uses malloc to allocate memory. It is guaranteed that malloc is
|
||||
* called at most once for every call of this function. If you need to avoid dynamic
|
||||
* memory allocation entirely, see secp256k1_context_static and the functions in
|
||||
* secp256k1_preallocated.h.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).
|
||||
*/
|
||||
context_create(xm_flags: Flags): PointerContext;
|
||||
/** Compute the keypair for a secret key.
|
||||
*
|
||||
* Returns: 1: secret was valid, keypair is ready to use
|
||||
* 0: secret was invalid, try again with a different secret
|
||||
* Args: ctx: pointer to a context object, initialized for signing.
|
||||
* Out: keypair: pointer to the created keypair.
|
||||
* In: seckey: pointer to a 32-byte secret key.
|
||||
*/
|
||||
keypair_create(ctx: PointerContext, keypair: PointerKeypair, secret: Pointer<32>): BinaryResult;
|
||||
/** Get the x-only public key from a keypair.
|
||||
*
|
||||
* This is the same as calling secp256k1_keypair_pub and then
|
||||
* secp256k1_xonly_pubkey_from_pubkey.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set
|
||||
* to the keypair public key after converting it to an
|
||||
* xonly_pubkey. If not, it's set to an invalid value.
|
||||
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
|
||||
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
|
||||
* In: keypair: pointer to a keypair.
|
||||
*/
|
||||
keypair_xonly_pub(ctx: PointerContext, pubkey: PointerXOnlyKey, pk_parity: Pointer | null, keypair: PointerKeypair): BinaryResult;
|
||||
/** Parse a 32-byte sequence into a xonly_pubkey object.
|
||||
*
|
||||
* Returns: 1 if the public key was fully valid.
|
||||
* 0 if the public key could not be parsed or is invalid.
|
||||
*
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
|
||||
* parsed version of input. If not, it's set to an invalid value.
|
||||
* In: input32: pointer to a serialized xonly_pubkey.
|
||||
*/
|
||||
xonly_pubkey_parse(ctx: PointerContext, pubkey: PointerXOnlyKey, input32: Pointer<32>): BinaryResult;
|
||||
/** Serialize an xonly_pubkey object into a 32-byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
*
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: output32: a pointer to a 32-byte array to place the serialized key in.
|
||||
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key.
|
||||
*/
|
||||
xonly_pubkey_serialize(ctx: PointerContext, output32: Pointer<32>, pubkey: PointerXOnlyKey): BinaryResult;
|
||||
/** Create a Schnorr signature.
|
||||
*
|
||||
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
|
||||
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
|
||||
* abort if it fails.
|
||||
*
|
||||
* This function only signs 32-byte messages. If you have messages of a
|
||||
* different size (or the same size but without a context-specific tag
|
||||
* prefix), it is recommended to create a 32-byte message hash with
|
||||
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
|
||||
* providing an context-specific tag for domain separation. This prevents
|
||||
* signatures from being valid in multiple contexts by accident.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object, initialized for signing.
|
||||
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
|
||||
* In: msg32: the 32-byte message being signed.
|
||||
* keypair: pointer to an initialized keypair.
|
||||
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
|
||||
* this, it is only supplemental to security and can be NULL. A
|
||||
* NULL argument is treated the same as an all-zero one. See
|
||||
* BIP-340 "Default Signing" for a full explanation of this
|
||||
* argument and for guidance if randomness is expensive.
|
||||
*/
|
||||
schnorrsig_sign32(ctx: PointerContext, sig64: PointerSig, msg32: Pointer<32>, keypair: PointerKeypair, aux_rand32: Pointer<32>): BinaryResult;
|
||||
/** Verify a Schnorr signature.
|
||||
*
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* Args: ctx: a secp256k1 context object, initialized for verification.
|
||||
* In: sig64: pointer to the 64-byte signature to verify.
|
||||
* msg: the message being verified. Can only be NULL if msglen is 0.
|
||||
* msglen: length of the message
|
||||
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
|
||||
*/
|
||||
schnorrsig_verify(ctx: PointerContext, sig64: PointerSig, msg32: Pointer<32>, msglen: number, pubkey: PointerXOnlyKey): BinaryResult;
|
||||
sha256_initialize(hash: PointerSha256): void;
|
||||
sha256_write(hash: PointerSha256, data: Pointer<number>, size: number): void;
|
||||
sha256_finalize(hash: PointerSha256, out32: Pointer<32>): void;
|
||||
}
|
||||
41
thrower_daemon/node_modules/nostr-wasm/dist/api/secp256k1.d.ts
generated
vendored
Normal file
41
thrower_daemon/node_modules/nostr-wasm/dist/api/secp256k1.d.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/// <reference types="web" />
|
||||
/// <reference types="node" />
|
||||
/**
|
||||
* Wrapper instance providing operations backed by libsecp256k1 WASM module
|
||||
*/
|
||||
export interface Secp256k1 {
|
||||
/**
|
||||
* Generates a new private key using crypto secure random bytes and without modulo bias
|
||||
* @returns a new private key (32 bytes)
|
||||
*/
|
||||
gen_secret_key(): Uint8Array;
|
||||
/**
|
||||
* Computes the public key for a given private key
|
||||
* @param sk - the private key (32 bytes)
|
||||
* @returns the public key (32 bytes)
|
||||
*/
|
||||
get_public_key(sk: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* Signs the given message hash using the given private key.
|
||||
* @param sk - the private key
|
||||
* @param hash - the message hash (32 bytes)
|
||||
* @param entropy - optional entropy to use
|
||||
* @returns compact signature (64 bytes)`
|
||||
*/
|
||||
sign(sk: Uint8Array, hash: Uint8Array, ent?: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* Verifies the signature is valid for the given message hash and public key
|
||||
* @param signature - compact signature (64 bytes)
|
||||
* @param msg - the message hash (32 bytes)
|
||||
* @param pk - the public key
|
||||
*/
|
||||
verify(signature: Uint8Array, hash: Uint8Array, pk: Uint8Array): boolean;
|
||||
sha256(message: string): Uint8Array;
|
||||
}
|
||||
/**
|
||||
* Creates a new instance of the secp256k1 WASM and returns its ES wrapper
|
||||
* @param z_src - a Response containing the WASM binary, a Promise that resolves to one,
|
||||
* or the raw bytes to the WASM binary as a {@link BufferSource}
|
||||
* @returns the wrapper API
|
||||
*/
|
||||
export declare const WasmSecp256k1: (z_src: Promise<Response> | Response | BufferSource) => Promise<Secp256k1>;
|
||||
124
thrower_daemon/node_modules/nostr-wasm/dist/api/types.d.ts
generated
vendored
Normal file
124
thrower_daemon/node_modules/nostr-wasm/dist/api/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
import type { WasmExportsExtension } from '../gen/wasm.js';
|
||||
import type { Pointer } from '../types.js';
|
||||
export type PointerContext = Pointer<'context'>;
|
||||
export type PointerSeed = Pointer<'seed'>;
|
||||
export type PointerXOnlyKey = Pointer<'xonly_key'>;
|
||||
export type PointerKeypair = Pointer<'keypair'>;
|
||||
export type PointerSig = Pointer<'signature'>;
|
||||
export type PointerSha256 = Pointer<'sha256'>;
|
||||
export declare const enum ByteLens {
|
||||
PRIVATE_KEY = 32,
|
||||
KEYPAIR_LIB = 96,
|
||||
XONLY_KEY_LIB = 64,
|
||||
BIP340_SIG = 64,// secp256k1_bip340_signature: char [64];
|
||||
XONLY_PUBKEY = 32,// serialized
|
||||
MSG_HASH = 32,
|
||||
NONCE_ENTROPY = 32,
|
||||
SHA256_LIB = 104
|
||||
}
|
||||
export declare const enum Flags {
|
||||
CONTEXT_NONE = 1,
|
||||
CONTEXT_VERIFY = 257,
|
||||
CONTEXT_SIGN = 513,
|
||||
CONTEXT_DECLASSIFY = 1025
|
||||
}
|
||||
export declare const enum BinaryResult {
|
||||
SUCCESS = 1,
|
||||
FAILURE = 0
|
||||
}
|
||||
export interface Secp256k1WasmCore extends WasmExportsExtension {
|
||||
/** Create a secp256k1 context object (in dynamically allocated memory).
|
||||
*
|
||||
* This function uses malloc to allocate memory. It is guaranteed that malloc is
|
||||
* called at most once for every call of this function. If you need to avoid dynamic
|
||||
* memory allocation entirely, see secp256k1_context_static and the functions in
|
||||
* secp256k1_preallocated.h.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).
|
||||
*/
|
||||
context_create(xm_flags: Flags): PointerContext;
|
||||
/** Compute the keypair for a secret key.
|
||||
*
|
||||
* Returns: 1: secret was valid, keypair is ready to use
|
||||
* 0: secret was invalid, try again with a different secret
|
||||
* Args: ctx: pointer to a context object, initialized for signing.
|
||||
* Out: keypair: pointer to the created keypair.
|
||||
* In: seckey: pointer to a 32-byte secret key.
|
||||
*/
|
||||
keypair_create(ctx: PointerContext, keypair: PointerKeypair, secret: Pointer<32>): BinaryResult;
|
||||
/** Get the x-only public key from a keypair.
|
||||
*
|
||||
* This is the same as calling secp256k1_keypair_pub and then
|
||||
* secp256k1_xonly_pubkey_from_pubkey.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set
|
||||
* to the keypair public key after converting it to an
|
||||
* xonly_pubkey. If not, it's set to an invalid value.
|
||||
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
|
||||
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
|
||||
* In: keypair: pointer to a keypair.
|
||||
*/
|
||||
keypair_xonly_pub(ctx: PointerContext, pubkey: PointerXOnlyKey, pk_parity: Pointer | null, keypair: PointerKeypair): BinaryResult;
|
||||
/** Parse a 32-byte sequence into a xonly_pubkey object.
|
||||
*
|
||||
* Returns: 1 if the public key was fully valid.
|
||||
* 0 if the public key could not be parsed or is invalid.
|
||||
*
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
|
||||
* parsed version of input. If not, it's set to an invalid value.
|
||||
* In: input32: pointer to a serialized xonly_pubkey.
|
||||
*/
|
||||
xonly_pubkey_parse(ctx: PointerContext, pubkey: PointerXOnlyKey, input32: Pointer<32>): BinaryResult;
|
||||
/** Serialize an xonly_pubkey object into a 32-byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
*
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: output32: a pointer to a 32-byte array to place the serialized key in.
|
||||
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key.
|
||||
*/
|
||||
xonly_pubkey_serialize(ctx: PointerContext, output32: Pointer<32>, pubkey: PointerXOnlyKey): BinaryResult;
|
||||
/** Create a Schnorr signature.
|
||||
*
|
||||
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
|
||||
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
|
||||
* abort if it fails.
|
||||
*
|
||||
* This function only signs 32-byte messages. If you have messages of a
|
||||
* different size (or the same size but without a context-specific tag
|
||||
* prefix), it is recommended to create a 32-byte message hash with
|
||||
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
|
||||
* providing an context-specific tag for domain separation. This prevents
|
||||
* signatures from being valid in multiple contexts by accident.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object, initialized for signing.
|
||||
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
|
||||
* In: msg32: the 32-byte message being signed.
|
||||
* keypair: pointer to an initialized keypair.
|
||||
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
|
||||
* this, it is only supplemental to security and can be NULL. A
|
||||
* NULL argument is treated the same as an all-zero one. See
|
||||
* BIP-340 "Default Signing" for a full explanation of this
|
||||
* argument and for guidance if randomness is expensive.
|
||||
*/
|
||||
schnorrsig_sign32(ctx: PointerContext, sig64: PointerSig, msg32: Pointer<32>, keypair: PointerKeypair, aux_rand32: Pointer<32>): BinaryResult;
|
||||
/** Verify a Schnorr signature.
|
||||
*
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* Args: ctx: a secp256k1 context object, initialized for verification.
|
||||
* In: sig64: pointer to the 64-byte signature to verify.
|
||||
* msg: the message being verified. Can only be NULL if msglen is 0.
|
||||
* msglen: length of the message
|
||||
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
|
||||
*/
|
||||
schnorrsig_verify(ctx: PointerContext, sig64: PointerSig, msg32: Pointer<32>, msglen: number, pubkey: PointerXOnlyKey): BinaryResult;
|
||||
sha256_initialize(hash: PointerSha256): void;
|
||||
sha256_write(hash: PointerSha256, data: Pointer<number>, size: number): void;
|
||||
sha256_finalize(hash: PointerSha256, out32: Pointer<32>): void;
|
||||
}
|
||||
3
thrower_daemon/node_modules/nostr-wasm/dist/api/wasm-env.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/nostr-wasm/dist/api/wasm-env.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/// <reference types="web" />
|
||||
import type { WasmImports } from 'src/types';
|
||||
export declare function defineWasmEnv(label: string): readonly [WasmImports, (d_memory: WebAssembly.Memory) => readonly [ArrayBuffer, Uint8Array, Uint32Array]];
|
||||
27
thrower_daemon/node_modules/nostr-wasm/dist/gen/wasm.d.ts
generated
vendored
Normal file
27
thrower_daemon/node_modules/nostr-wasm/dist/gen/wasm.d.ts
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/// <reference types="web" />
|
||||
import type { Pointer, WasmImports, WasmExports } from '../types.js';
|
||||
export interface WasmImportsExtension extends WasmImports {
|
||||
}
|
||||
export interface WasmExportsExtension extends WasmExports {
|
||||
sha256_initialize: Function;
|
||||
sha256_write: Function;
|
||||
sha256_finalize: Function;
|
||||
context_create: Function;
|
||||
xonly_pubkey_parse: Function;
|
||||
xonly_pubkey_serialize: Function;
|
||||
keypair_create: Function;
|
||||
keypair_xonly_pub: Function;
|
||||
schnorrsig_sign32: Function;
|
||||
schnorrsig_verify: Function;
|
||||
}
|
||||
export declare const map_wasm_imports: (g_imports: WasmImportsExtension) => {
|
||||
a: {
|
||||
a: () => void;
|
||||
f: <nb_size extends number>(ip_dst: Pointer<nb_size>, ip_src: Pointer<nb_size>, nb_size: nb_size) => Uint8Array;
|
||||
d: (nb_size: number) => void;
|
||||
e: () => number;
|
||||
c: () => number;
|
||||
b: (i_fd: number, ip_iov: Pointer<number>, nl_iovs: number, ip_written: Pointer<number>) => 0;
|
||||
};
|
||||
};
|
||||
export declare const map_wasm_exports: <g_extension extends WasmExportsExtension = WasmExportsExtension>(g_exports: WebAssembly.Exports) => g_extension;
|
||||
1
thrower_daemon/node_modules/nostr-wasm/dist/generate.d.ts
generated
vendored
Normal file
1
thrower_daemon/node_modules/nostr-wasm/dist/generate.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
3
thrower_daemon/node_modules/nostr-wasm/dist/gzipped.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/nostr-wasm/dist/gzipped.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './headless.js';
|
||||
import { type Nostr } from './api/nostr.js';
|
||||
export declare const initNostrWasm: () => Promise<Nostr>;
|
||||
44
thrower_daemon/node_modules/nostr-wasm/dist/gzipped.js
generated
vendored
Normal file
44
thrower_daemon/node_modules/nostr-wasm/dist/gzipped.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
thrower_daemon/node_modules/nostr-wasm/dist/headless.d.ts
generated
vendored
Normal file
2
thrower_daemon/node_modules/nostr-wasm/dist/headless.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export type { Nostr } from './api/nostr.js';
|
||||
export { NostrWasm } from './api/nostr.js';
|
||||
3
thrower_daemon/node_modules/nostr-wasm/dist/main.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/nostr-wasm/dist/main.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './headless.js';
|
||||
import { type Nostr } from './api/nostr.js';
|
||||
export declare const initNostrWasm: () => Promise<Nostr>;
|
||||
9
thrower_daemon/node_modules/nostr-wasm/dist/main.js
generated
vendored
Normal file
9
thrower_daemon/node_modules/nostr-wasm/dist/main.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
248
thrower_daemon/node_modules/nostr-wasm/dist/nostr.js
generated
vendored
Normal file
248
thrower_daemon/node_modules/nostr-wasm/dist/nostr.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
function defineWasmEnv(label) {
|
||||
label += ': ';
|
||||
let AB_HEAP;
|
||||
let ATU8_HEAP;
|
||||
let ATU32_HEAP;
|
||||
// eslint-disable-next-line no-console
|
||||
const console_out = (s_channel, s_out) => console[s_channel](label + s_out.replace(/\0/g, '\n'));
|
||||
let s_error = '';
|
||||
// for converting bytes to text
|
||||
const utf8 = new TextDecoder();
|
||||
const h_fds = {
|
||||
// stdout
|
||||
1(s_out) {
|
||||
console_out('debug', s_out);
|
||||
},
|
||||
// stderr
|
||||
2(s_out) {
|
||||
console_out('error', (s_error = s_out));
|
||||
}
|
||||
};
|
||||
const imports = {
|
||||
abort() {
|
||||
throw Error(label + (s_error || 'An unknown error occurred'));
|
||||
},
|
||||
memcpy: (ip_dst, ip_src, nb_size) => ATU8_HEAP.copyWithin(ip_dst, ip_src, ip_src + nb_size),
|
||||
resize(w) {
|
||||
throw Error(label + `Out of memory (resizing ${w})`);
|
||||
},
|
||||
write(i_fd, ip_iov, nl_iovs, ip_written) {
|
||||
// output string
|
||||
let s_out = '';
|
||||
// track number of bytes read from buffers
|
||||
let cb_read = 0;
|
||||
// each pending iov
|
||||
for (let i_iov = 0; i_iov < nl_iovs; i_iov++) {
|
||||
// start of buffer in memory
|
||||
const ip_start = ATU32_HEAP[ip_iov >> 2];
|
||||
// size of buffer
|
||||
const nb_len = ATU32_HEAP[(ip_iov + 4) >> 2];
|
||||
ip_iov += 8;
|
||||
// extract text from buffer
|
||||
s_out += utf8.decode(ATU8_HEAP.subarray(ip_start, ip_start + nb_len));
|
||||
// update number of bytes read
|
||||
cb_read += nb_len;
|
||||
}
|
||||
// route to fd
|
||||
if (h_fds[i_fd]) {
|
||||
h_fds[i_fd](s_out);
|
||||
}
|
||||
else {
|
||||
// no fd found
|
||||
throw new Error(`libsecp256k1 tried writing to non-open file descriptor: ${i_fd}\n${s_out}`);
|
||||
}
|
||||
// write bytes read
|
||||
ATU32_HEAP[ip_written >> 2] = cb_read;
|
||||
// no error
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
return [
|
||||
imports,
|
||||
(d_memory) => [
|
||||
(AB_HEAP = d_memory.buffer),
|
||||
(ATU8_HEAP = new Uint8Array(AB_HEAP)),
|
||||
(ATU32_HEAP = new Uint32Array(AB_HEAP))
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* ================================
|
||||
* GENERATED FILE WARNING
|
||||
* Do not edit this file manually.
|
||||
* ================================
|
||||
*/
|
||||
const map_wasm_imports = (g_imports) => ({
|
||||
a: {
|
||||
a: g_imports.abort,
|
||||
f: g_imports.memcpy,
|
||||
d: g_imports.resize,
|
||||
e: () => 52, // _fd_close,
|
||||
c: () => 70, // _fd_seek,
|
||||
b: g_imports.write,
|
||||
},
|
||||
});
|
||||
const map_wasm_exports = (g_exports) => ({
|
||||
malloc: g_exports['i'],
|
||||
free: g_exports['j'],
|
||||
sha256_initialize: g_exports['l'],
|
||||
sha256_write: g_exports['m'],
|
||||
sha256_finalize: g_exports['n'],
|
||||
context_create: g_exports['o'],
|
||||
xonly_pubkey_parse: g_exports['p'],
|
||||
xonly_pubkey_serialize: g_exports['q'],
|
||||
keypair_create: g_exports['r'],
|
||||
keypair_xonly_pub: g_exports['s'],
|
||||
schnorrsig_sign32: g_exports['t'],
|
||||
schnorrsig_verify: g_exports['u'],
|
||||
sbrk: g_exports['sbrk'],
|
||||
memory: g_exports['g'],
|
||||
init: () => g_exports['h'](),
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a new instance of the secp256k1 WASM and returns the Nostr wrapper
|
||||
* @param z_src - a Response containing the WASM binary, a Promise that resolves to one,
|
||||
* or the raw bytes to the WASM binary as a {@link BufferSource}
|
||||
* @returns the wrapper API
|
||||
*/
|
||||
const NostrWasm = async (z_src) => {
|
||||
// prepare the runtime
|
||||
const [defs, f_bind_heap] = defineWasmEnv('nostr-wasm');
|
||||
const g_imports = map_wasm_imports(defs);
|
||||
// prep the wasm module
|
||||
let d_wasm;
|
||||
// instantiate wasm binary by streaming the response bytes
|
||||
if (z_src instanceof Response || z_src instanceof Promise) {
|
||||
d_wasm = await WebAssembly.instantiateStreaming(z_src, g_imports);
|
||||
}
|
||||
else {
|
||||
// instantiate using raw binary
|
||||
d_wasm = await WebAssembly.instantiate(z_src, g_imports);
|
||||
}
|
||||
// create the exports struct
|
||||
const g_wasm = map_wasm_exports(d_wasm.instance.exports);
|
||||
// bind the heap and ref its view(s)
|
||||
const [, ATU8_HEAP] = f_bind_heap(g_wasm.memory);
|
||||
// call into the wasm module's init method
|
||||
g_wasm.init();
|
||||
const ip_sk = g_wasm.malloc(32 /* ByteLens.PRIVATE_KEY */);
|
||||
const ip_ent = g_wasm.malloc(32 /* ByteLens.NONCE_ENTROPY */);
|
||||
const ip_msg_hash = g_wasm.malloc(32 /* ByteLens.MSG_HASH */);
|
||||
// scratch spaces
|
||||
const ip_pubkey_scratch = g_wasm.malloc(32 /* ByteLens.XONLY_PUBKEY */);
|
||||
const ip_sig_scratch = g_wasm.malloc(64 /* ByteLens.BIP340_SIG */);
|
||||
// library handle: secp256k1_keypair;
|
||||
const ip_keypair = g_wasm.malloc(96 /* ByteLens.KEYPAIR_LIB */);
|
||||
// library handle: secp256k1_xonly_pubkey;
|
||||
const ip_xonly_pubkey = g_wasm.malloc(64 /* ByteLens.XONLY_KEY_LIB */);
|
||||
// library handle: secp256k1_sha256;
|
||||
const ip_sha256 = g_wasm.malloc(104 /* ByteLens.SHA256_LIB */);
|
||||
// create a reusable context
|
||||
const ip_ctx = g_wasm.context_create(513 /* Flags.CONTEXT_SIGN */ | 257 /* Flags.CONTEXT_VERIFY */);
|
||||
// an encoder for hashing strings
|
||||
const utf8 = new TextEncoder();
|
||||
/**
|
||||
* Puts the given private key into program memory, runs the given callback, then zeroes out the key
|
||||
* @param atu8_sk - the private key
|
||||
* @param f_use - callback to use the key
|
||||
* @returns whatever the callback returns
|
||||
*/
|
||||
const with_keypair = (atu8_sk, f_use) => {
|
||||
// prep callback return
|
||||
let w_return;
|
||||
// in case of any exception..
|
||||
try {
|
||||
// copy input bytes into place
|
||||
ATU8_HEAP.set(atu8_sk, ip_sk);
|
||||
// instantiate keypair
|
||||
g_wasm.keypair_create(ip_ctx, ip_keypair, ip_sk);
|
||||
// use private key
|
||||
w_return = f_use();
|
||||
}
|
||||
finally {
|
||||
// zero-out private key and keypair
|
||||
ATU8_HEAP.fill(1, ip_sk, ip_sk + 32 /* ByteLens.PRIVATE_KEY */);
|
||||
ATU8_HEAP.fill(2, ip_keypair, ip_keypair + 96 /* ByteLens.KEYPAIR_LIB */);
|
||||
}
|
||||
// forward result
|
||||
return w_return;
|
||||
};
|
||||
const compute_event_id = (event) => {
|
||||
const message = utf8.encode(`[0,"${event.pubkey}",${event.created_at},${event.kind},${JSON.stringify(event.tags)},${JSON.stringify(event.content)}]`);
|
||||
const ip_message = g_wasm.malloc(message.length);
|
||||
ATU8_HEAP.set(message, ip_message);
|
||||
g_wasm.sha256_initialize(ip_sha256);
|
||||
g_wasm.sha256_write(ip_sha256, ip_message, message.length);
|
||||
g_wasm.sha256_finalize(ip_sha256, ip_msg_hash);
|
||||
g_wasm.free(ip_message);
|
||||
return ATU8_HEAP.slice(ip_msg_hash, ip_msg_hash + 32 /* ByteLens.MSG_HASH */);
|
||||
};
|
||||
return {
|
||||
generateSecretKey: () => crypto.getRandomValues(new Uint8Array(32 /* ByteLens.PRIVATE_KEY */)),
|
||||
getPublicKey(sk) {
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
with_keypair(sk, () => g_wasm.keypair_xonly_pub(ip_ctx, ip_xonly_pubkey, null, ip_keypair))) {
|
||||
throw Error('failed to get pubkey from keypair');
|
||||
}
|
||||
// serialize the public key
|
||||
g_wasm.xonly_pubkey_serialize(ip_ctx, ip_pubkey_scratch, ip_xonly_pubkey);
|
||||
// extract result
|
||||
return ATU8_HEAP.slice(ip_pubkey_scratch, ip_pubkey_scratch + 32 /* ByteLens.XONLY_PUBKEY */);
|
||||
},
|
||||
finalizeEvent(event, seckey, ent) {
|
||||
with_keypair(seckey, () => {
|
||||
// get public key (as in getPublicKey function above)
|
||||
g_wasm.keypair_xonly_pub(ip_ctx, ip_xonly_pubkey, null, ip_keypair);
|
||||
g_wasm.xonly_pubkey_serialize(ip_ctx, ip_pubkey_scratch, ip_xonly_pubkey);
|
||||
const pubkey = ATU8_HEAP.slice(ip_pubkey_scratch, ip_pubkey_scratch + 32 /* ByteLens.XONLY_PUBKEY */);
|
||||
event.pubkey = toHex(pubkey);
|
||||
// compute event id
|
||||
event.id = toHex(compute_event_id(event));
|
||||
// copy entropy bytes into place, if they are provided
|
||||
if (!ent && crypto.getRandomValues) {
|
||||
ATU8_HEAP.set(crypto.getRandomValues(new Uint8Array(32)), ip_ent);
|
||||
}
|
||||
// perform signature (ip_msg_hash is already set from procedure above)
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
g_wasm.schnorrsig_sign32(ip_ctx, ip_sig_scratch, ip_msg_hash, ip_keypair, ip_ent)) {
|
||||
throw Error('failed to sign');
|
||||
}
|
||||
});
|
||||
const sig = ATU8_HEAP.slice(ip_sig_scratch, ip_sig_scratch + 64 /* ByteLens.BIP340_SIG */);
|
||||
event.sig = toHex(sig);
|
||||
},
|
||||
verifyEvent(event) {
|
||||
const id = fromHex(event.id);
|
||||
// check event hash
|
||||
const computed = compute_event_id(event);
|
||||
for (let i = 0; i < id.length; i++) {
|
||||
if (id[i] !== computed[i])
|
||||
throw Error('id is invalid');
|
||||
}
|
||||
// copy event data into place
|
||||
ATU8_HEAP.set(fromHex(event.sig), ip_sig_scratch);
|
||||
ATU8_HEAP.set(fromHex(event.id), ip_msg_hash);
|
||||
ATU8_HEAP.set(fromHex(event.pubkey), ip_pubkey_scratch);
|
||||
// parse the public key
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
g_wasm.xonly_pubkey_parse(ip_ctx, ip_xonly_pubkey, ip_pubkey_scratch)) {
|
||||
throw Error('pubkey is invalid');
|
||||
}
|
||||
// verify the signature
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
g_wasm.schnorrsig_verify(ip_ctx, ip_sig_scratch, ip_msg_hash, 32 /* ByteLens.MSG_HASH */, ip_xonly_pubkey)) {
|
||||
throw Error('signature is invalid');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
function toHex(bytes) {
|
||||
return bytes.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '');
|
||||
}
|
||||
function fromHex(hex) {
|
||||
return new Uint8Array(hex.length / 2).map((_, i) => parseInt(hex.slice(i * 2, i * 2 + 2), 16));
|
||||
}
|
||||
|
||||
export { NostrWasm as N };
|
||||
230
thrower_daemon/node_modules/nostr-wasm/dist/secp256k1.js
generated
vendored
Normal file
230
thrower_daemon/node_modules/nostr-wasm/dist/secp256k1.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
const emsimp = (f_map_imports, s_tag) => {
|
||||
s_tag += ': ';
|
||||
let AB_HEAP;
|
||||
let ATU8_HEAP;
|
||||
let ATU32_HEAP;
|
||||
// eslint-disable-next-line no-console
|
||||
const console_out = (s_channel, s_out) => console[s_channel](s_tag + s_out.replace(/\0/g, '\n'));
|
||||
let s_error = '';
|
||||
// for converting bytes to text
|
||||
const utf8 = new TextDecoder();
|
||||
const h_fds = {
|
||||
// stdout
|
||||
1(s_out) {
|
||||
console_out('debug', s_out);
|
||||
},
|
||||
// stderr
|
||||
2(s_out) {
|
||||
console_out('error', (s_error = s_out));
|
||||
}
|
||||
};
|
||||
const g_imports = f_map_imports({
|
||||
abort() {
|
||||
throw Error(s_tag + (s_error || 'An unknown error occurred'));
|
||||
},
|
||||
memcpy: (ip_dst, ip_src, nb_size) => ATU8_HEAP.copyWithin(ip_dst, ip_src, ip_src + nb_size),
|
||||
resize(_) {
|
||||
throw Error(s_tag + 'Out of memory');
|
||||
},
|
||||
write(i_fd, ip_iov, nl_iovs, ip_written) {
|
||||
// output string
|
||||
let s_out = '';
|
||||
// track number of bytes read from buffers
|
||||
let cb_read = 0;
|
||||
// each pending iov
|
||||
for (let i_iov = 0; i_iov < nl_iovs; i_iov++) {
|
||||
// start of buffer in memory
|
||||
const ip_start = ATU32_HEAP[ip_iov >> 2];
|
||||
// size of buffer
|
||||
const nb_len = ATU32_HEAP[(ip_iov + 4) >> 2];
|
||||
ip_iov += 8;
|
||||
// extract text from buffer
|
||||
s_out += utf8.decode(ATU8_HEAP.subarray(ip_start, ip_start + nb_len));
|
||||
// update number of bytes read
|
||||
cb_read += nb_len;
|
||||
}
|
||||
// route to fd
|
||||
if (h_fds[i_fd]) {
|
||||
h_fds[i_fd](s_out);
|
||||
}
|
||||
else {
|
||||
// no fd found
|
||||
throw new Error(`libsecp256k1 tried writing to non-open file descriptor: ${i_fd}\n${s_out}`);
|
||||
}
|
||||
// write bytes read
|
||||
ATU32_HEAP[ip_written >> 2] = cb_read;
|
||||
// no error
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return [
|
||||
g_imports,
|
||||
(d_memory) => [
|
||||
(AB_HEAP = d_memory.buffer),
|
||||
(ATU8_HEAP = new Uint8Array(AB_HEAP)),
|
||||
(ATU32_HEAP = new Uint32Array(AB_HEAP))
|
||||
]
|
||||
];
|
||||
};
|
||||
|
||||
/*
|
||||
* ================================
|
||||
* GENERATED FILE WARNING
|
||||
* Do not edit this file manually.
|
||||
* ================================
|
||||
*/
|
||||
const map_wasm_imports = (g_imports) => ({
|
||||
a: {
|
||||
a: g_imports.abort,
|
||||
f: g_imports.memcpy,
|
||||
d: g_imports.resize,
|
||||
e: () => 52, // _fd_close,
|
||||
c: () => 70, // _fd_seek,
|
||||
b: g_imports.write,
|
||||
},
|
||||
});
|
||||
const map_wasm_exports = (g_exports) => ({
|
||||
malloc: g_exports['i'],
|
||||
free: g_exports['j'],
|
||||
sha256_initialize: g_exports['l'],
|
||||
sha256_write: g_exports['m'],
|
||||
sha256_finalize: g_exports['n'],
|
||||
context_create: g_exports['o'],
|
||||
xonly_pubkey_parse: g_exports['p'],
|
||||
xonly_pubkey_serialize: g_exports['q'],
|
||||
keypair_create: g_exports['r'],
|
||||
keypair_xonly_pub: g_exports['s'],
|
||||
schnorrsig_sign32: g_exports['t'],
|
||||
schnorrsig_verify: g_exports['u'],
|
||||
sbrk: g_exports['sbrk'],
|
||||
memory: g_exports['g'],
|
||||
init: () => g_exports['h'](),
|
||||
});
|
||||
|
||||
const S_TAG_BIP340_VERIFY = 'BIP340 verify: ';
|
||||
const S_REASON_INVALID_SK = 'Invalid private key';
|
||||
const S_REASON_INVALID_PK = 'Invalid public key';
|
||||
/**
|
||||
* Creates a new instance of the secp256k1 WASM and returns its ES wrapper
|
||||
* @param z_src - a Response containing the WASM binary, a Promise that resolves to one,
|
||||
* or the raw bytes to the WASM binary as a {@link BufferSource}
|
||||
* @returns the wrapper API
|
||||
*/
|
||||
const WasmSecp256k1 = async (z_src) => {
|
||||
// prepare the runtime
|
||||
const [g_imports, f_bind_heap] = emsimp(map_wasm_imports, 'wasm-secp256k1');
|
||||
// prep the wasm module
|
||||
let d_wasm;
|
||||
// instantiate wasm binary by streaming the response bytes
|
||||
if (z_src instanceof Response || z_src instanceof Promise) {
|
||||
d_wasm = await WebAssembly.instantiateStreaming(z_src, g_imports);
|
||||
}
|
||||
else {
|
||||
// instantiate using raw binary
|
||||
d_wasm = await WebAssembly.instantiate(z_src, g_imports);
|
||||
}
|
||||
// create the libsecp256k1 exports struct
|
||||
const g_wasm = map_wasm_exports(d_wasm.instance.exports);
|
||||
// bind the heap and ref its view(s)
|
||||
const [, ATU8_HEAP] = f_bind_heap(g_wasm.memory);
|
||||
// call into the wasm module's init method
|
||||
g_wasm.init();
|
||||
const ip_sk = g_wasm.malloc(32 /* ByteLens.PRIVATE_KEY */);
|
||||
const ip_ent = g_wasm.malloc(32 /* ByteLens.NONCE_ENTROPY */);
|
||||
const ip_msg_hash = g_wasm.malloc(32 /* ByteLens.MSG_HASH */);
|
||||
// scratch spaces
|
||||
const ip_pubkey_scratch = g_wasm.malloc(32 /* ByteLens.XONLY_PUBKEY */);
|
||||
const ip_sig_scratch = g_wasm.malloc(64 /* ByteLens.BIP340_SIG */);
|
||||
// library handle: secp256k1_keypair;
|
||||
const ip_keypair = g_wasm.malloc(96 /* ByteLens.KEYPAIR_LIB */);
|
||||
// library handle: secp256k1_xonly_pubkey;
|
||||
const ip_xonly_pubkey = g_wasm.malloc(64 /* ByteLens.XONLY_KEY_LIB */);
|
||||
// library handle: secp256k1_sha256;
|
||||
const ip_sha256 = g_wasm.malloc(104 /* ByteLens.SHA256_LIB */);
|
||||
// create a reusable context
|
||||
const ip_ctx = g_wasm.context_create(513 /* Flags.CONTEXT_SIGN */ | 257 /* Flags.CONTEXT_VERIFY */);
|
||||
// an encoder for hashing strings
|
||||
const utf8 = new TextEncoder();
|
||||
/**
|
||||
* Puts the given private key into program memory, runs the given callback, then zeroes out the key
|
||||
* @param atu8_sk - the private key
|
||||
* @param f_use - callback to use the key
|
||||
* @returns whatever the callback returns
|
||||
*/
|
||||
const with_keypair = (atu8_sk, f_use) => {
|
||||
// prep callback return
|
||||
let w_return;
|
||||
// in case of any exception..
|
||||
try {
|
||||
// copy input bytes into place
|
||||
ATU8_HEAP.set(atu8_sk, ip_sk);
|
||||
// instantiate keypair
|
||||
g_wasm.keypair_create(ip_ctx, ip_keypair, ip_sk);
|
||||
// use private key
|
||||
w_return = f_use();
|
||||
}
|
||||
finally {
|
||||
// zero-out private key and keypair
|
||||
ATU8_HEAP.fill(1, ip_sk, ip_sk + 32 /* ByteLens.PRIVATE_KEY */);
|
||||
ATU8_HEAP.fill(2, ip_keypair, ip_keypair + 96 /* ByteLens.KEYPAIR_LIB */);
|
||||
}
|
||||
// forward result
|
||||
return w_return;
|
||||
};
|
||||
return {
|
||||
gen_secret_key: () => crypto.getRandomValues(new Uint8Array(32 /* ByteLens.PRIVATE_KEY */)),
|
||||
get_public_key(atu8_sk) {
|
||||
// while using the private key, compute its corresponding public key; from the docs:
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
with_keypair(atu8_sk, () => g_wasm.keypair_xonly_pub(ip_ctx, ip_xonly_pubkey, null, ip_keypair))) {
|
||||
throw Error('sk_to_pk: ' + S_REASON_INVALID_SK);
|
||||
}
|
||||
// serialize the public key
|
||||
g_wasm.xonly_pubkey_serialize(ip_ctx, ip_pubkey_scratch, ip_xonly_pubkey);
|
||||
// extract result
|
||||
return ATU8_HEAP.slice(ip_pubkey_scratch, ip_pubkey_scratch + 32 /* ByteLens.XONLY_PUBKEY */);
|
||||
},
|
||||
sign(atu8_sk, atu8_hash, atu8_ent) {
|
||||
// copy message hash bytes into place
|
||||
ATU8_HEAP.set(atu8_hash, ip_msg_hash);
|
||||
// copy entropy bytes into place
|
||||
if (!atu8_ent && crypto.getRandomValues) {
|
||||
ATU8_HEAP.set(crypto.getRandomValues(new Uint8Array(32)), ip_ent);
|
||||
}
|
||||
// while using the private key, sign the given message hash
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
with_keypair(atu8_sk, () => g_wasm.schnorrsig_sign32(ip_ctx, ip_sig_scratch, ip_msg_hash, ip_keypair, ip_ent))) {
|
||||
throw Error('BIP-340 sign: ' + S_REASON_INVALID_SK);
|
||||
}
|
||||
// return serialized signature
|
||||
return ATU8_HEAP.slice(ip_sig_scratch, ip_sig_scratch + 64 /* ByteLens.BIP340_SIG */);
|
||||
},
|
||||
verify(atu8_signature, atu8_hash, atu8_pk) {
|
||||
// copy signature bytes into place
|
||||
ATU8_HEAP.set(atu8_signature, ip_sig_scratch);
|
||||
// copy message hash bytes into place
|
||||
ATU8_HEAP.set(atu8_hash, ip_msg_hash);
|
||||
// copy pubkey bytes into place
|
||||
ATU8_HEAP.set(atu8_pk, ip_pubkey_scratch);
|
||||
// parse the public key
|
||||
if (1 /* BinaryResult.SUCCESS */ !==
|
||||
g_wasm.xonly_pubkey_parse(ip_ctx, ip_xonly_pubkey, ip_pubkey_scratch)) {
|
||||
throw Error(S_TAG_BIP340_VERIFY + S_REASON_INVALID_PK);
|
||||
}
|
||||
// verify the signature
|
||||
return (1 /* BinaryResult.SUCCESS */ ===
|
||||
g_wasm.schnorrsig_verify(ip_ctx, ip_sig_scratch, ip_msg_hash, 32 /* ByteLens.MSG_HASH */, ip_xonly_pubkey));
|
||||
},
|
||||
sha256(message) {
|
||||
const ip_message = g_wasm.malloc(message.length);
|
||||
const data = utf8.encode(message);
|
||||
ATU8_HEAP.set(data, ip_message);
|
||||
g_wasm.sha256_initialize(ip_sha256);
|
||||
g_wasm.sha256_write(ip_sha256, ip_message, message.length);
|
||||
g_wasm.sha256_finalize(ip_sha256, ip_msg_hash);
|
||||
return ATU8_HEAP.slice(ip_msg_hash, ip_msg_hash + 32 /* ByteLens.MSG_HASH */);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export { WasmSecp256k1 as W };
|
||||
22
thrower_daemon/node_modules/nostr-wasm/dist/types.d.ts
generated
vendored
Normal file
22
thrower_daemon/node_modules/nostr-wasm/dist/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference types="web" />
|
||||
export type Pointer<w_subtype = unknown> = number & {
|
||||
POINTER_TYPE: w_subtype;
|
||||
};
|
||||
export type ByteSize = number;
|
||||
export type ByteDelta = number;
|
||||
export type ByteOffset = number;
|
||||
export type FileDescriptor = number;
|
||||
export type SeekWhence = number;
|
||||
export interface WasmImports {
|
||||
abort: () => void;
|
||||
memcpy: <nb_size extends ByteSize>(ip_dst: Pointer<nb_size>, ip_src: Pointer<nb_size>, nb_size: nb_size) => Uint8Array;
|
||||
resize: (nb_size: ByteSize) => void;
|
||||
write: (i_fd: FileDescriptor, ip_iov: Pointer<number>, nl_iovs: number, ip_written: Pointer<number>) => 0;
|
||||
}
|
||||
export interface WasmExports {
|
||||
malloc: <w_pointer_type extends Pointer, nb_size extends ByteSize = ByteSize>(nb_size: nb_size) => Pointer extends w_pointer_type ? Pointer<nb_size> : w_pointer_type;
|
||||
free: (ip_ptr: Pointer) => void;
|
||||
sbrk: (nb_change: ByteDelta) => Pointer;
|
||||
memory: WebAssembly.Memory;
|
||||
init: VoidFunction;
|
||||
}
|
||||
37
thrower_daemon/node_modules/nostr-wasm/package.json
generated
vendored
Normal file
37
thrower_daemon/node_modules/nostr-wasm/package.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "nostr-wasm",
|
||||
"description": "nostr stuff in wasm",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "dist/main.js",
|
||||
"files": [
|
||||
"dist/",
|
||||
"public/"
|
||||
],
|
||||
"exports": {
|
||||
".": "./dist/main.js",
|
||||
"./headless": "./dist/headless.js",
|
||||
"./gzipped": "./dist/gzipped.js"
|
||||
},
|
||||
"author": "fiatjaf <fiatjaf@gmail.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@blake.regalia/tsconfig": "^0.1.2",
|
||||
"@rollup/plugin-typescript": "^11.1.5",
|
||||
"@rollup/plugin-wasm": "^6.2.2",
|
||||
"@rollup/pluginutils": "^5.0.5",
|
||||
"@types/node": "^20.8.10",
|
||||
"@types/web": "^0.0.119",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"acorn": "^8.11.2",
|
||||
"eslint": "^8.52.0",
|
||||
"eslint-plugin-unused-imports": "^3.0.0",
|
||||
"rollup": "^4.2.0",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
1
thrower_daemon/node_modules/nostr-wasm/public/out/secp256k1.js
generated
vendored
Normal file
1
thrower_daemon/node_modules/nostr-wasm/public/out/secp256k1.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var Module=globalThis.Module||{};var ENVIRONMENT_IS_NODE=typeof process=="object";if(ENVIRONMENT_IS_NODE){var fs=require("fs");Module["wasm"]=fs.readFileSync(__dirname+"/secp256k1.wasm")}var out=text=>console.log(text);var err=text=>console.error(text);function ready(){}function abort(what){throw what}var HEAP8,HEAP16,HEAP32,HEAPU8,HEAPU16,HEAPU32,HEAPF32,HEAPF64,wasmMemory;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b)}var noExitRuntime=Module["noExitRuntime"]||true;var _abort=()=>{abort("")};var _emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={varargs:undefined,get(){var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret}};var _fd_close=fd=>52;var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);return 70}var printCharBuffers=[null,[],[]];var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i<iovcnt;i++){var ptr=HEAPU32[iov>>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j<len;j++){printChar(fd,HEAPU8[ptr+j])}num+=len}HEAPU32[pnum>>2]=num;return 0};var wasmImports={a:_abort,f:_emscripten_memcpy_js,d:_emscripten_resize_heap,e:_fd_close,c:_fd_seek,b:_fd_write};function initRuntime(wasmExports){wasmExports["h"]()}var imports={"a":wasmImports};var _malloc,_free,_secp256k1_sha256_initialize,_secp256k1_sha256_write,_secp256k1_sha256_finalize,_secp256k1_context_create,_secp256k1_xonly_pubkey_parse,_secp256k1_xonly_pubkey_serialize,_secp256k1_keypair_create,_secp256k1_keypair_xonly_pub,_secp256k1_schnorrsig_sign32,_secp256k1_schnorrsig_verify,_sbrk;WebAssembly.instantiate(Module["wasm"],imports).then(output=>{var wasmExports=output.instance.exports;_malloc=wasmExports["i"];_free=wasmExports["j"];_secp256k1_sha256_initialize=wasmExports["l"];_secp256k1_sha256_write=wasmExports["m"];_secp256k1_sha256_finalize=wasmExports["n"];_secp256k1_context_create=wasmExports["o"];_secp256k1_xonly_pubkey_parse=wasmExports["p"];_secp256k1_xonly_pubkey_serialize=wasmExports["q"];_secp256k1_keypair_create=wasmExports["r"];_secp256k1_keypair_xonly_pub=wasmExports["s"];_secp256k1_schnorrsig_sign32=wasmExports["t"];_secp256k1_schnorrsig_verify=wasmExports["u"];_sbrk=wasmExports["sbrk"];wasmMemory=wasmExports["g"];updateMemoryViews();initRuntime(wasmExports);ready()});
|
||||
BIN
thrower_daemon/node_modules/nostr-wasm/public/out/secp256k1.wasm
generated
vendored
Executable file
BIN
thrower_daemon/node_modules/nostr-wasm/public/out/secp256k1.wasm
generated
vendored
Executable file
Binary file not shown.
Reference in New Issue
Block a user