Page MenuHomePhabricator

D17464.id51960.diff
No OneTemporary

D17464.id51960.diff

diff --git a/modules/ecash-lib/README.md b/modules/ecash-lib/README.md
--- a/modules/ecash-lib/README.md
+++ b/modules/ecash-lib/README.md
@@ -107,3 +107,4 @@
- 1.1.0 - Add support for the original pre-UAHF Bitcoin signatures, so we can sign transactions for other blockchains like BTC/DOGE/... [D17255](https://reviews.bitcoinabc.org/D17255)
- 1.2.0 - Add `Address` class for cashaddr and legacy addresses. [D17269](https://reviews.bitcoinabc.org/D17269)
- 1.2.1 - Patch type check causing txBuilder txs using change to fail in NodeJS environments [D17461](https://reviews.bitcoinabc.org/D17461)
+- 1.2.2 - Attach `Ecc` and `HASHES` to `globalThis` instead of dependency injection, so that they can work when `ecash-lib` is a dependency of another lib [D17464](https://reviews.bitcoinabc.org/D17464)
diff --git a/modules/ecash-lib/global.d.ts b/modules/ecash-lib/global.d.ts
new file mode 100644
--- /dev/null
+++ b/modules/ecash-lib/global.d.ts
@@ -0,0 +1,64 @@
+// Copyright (c) 2024 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * global.d.ts
+ *
+ * Extend globalThis to include a new namespace, ecashlib
+ * We use this namespace to store lib functions that are only
+ * available after initWasm()
+ *
+ * We store all lib methods in ecashlib namespace to reduce chances of
+ * namespace collision in global this
+ *
+ * In general, dependency injection is a better practice, and this is what
+ * ecash-lib used until 1.2.2
+ *
+ * However dependency injection caused issues with libraries that used ecash-lib
+ * as a dependency, like ecash-agora. Methods that "should" have been available
+ * after initWasm() would not be available.
+ *
+ * Resolved by adding to globalThis (as responsibly as possible)
+ */
+
+// BEGIN DUPLICATED CLASS DEFINITIONS
+
+/**
+ * Note
+ * These definitions are duplicated in src/ecc.ts
+ * Could not import it here as it leads to rel path errors in the
+ * published dependency when it is consumed by other apps
+ */
+
+/** Interface to abstract over Elliptic Curve Cryptography */
+export interface Ecc {
+ /** Derive a public key from secret key. */
+ derivePubkey(seckey: Uint8Array): Uint8Array;
+
+ /** Sign an ECDSA signature. msg needs to be a 32-byte hash */
+ ecdsaSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
+
+ /** Sign a Schnorr signature. msg needs to be a 32-byte hash */
+ schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
+}
+
+/** Ecc implementation using WebAssembly */
+export let Ecc: { new (): Ecc };
+// END DUPLICATED CLASS DEFINITIONS
+
+export interface EcashLibHashes {
+ sha256: (data: Uint8Array) => Uint8Array;
+ sha256d: (data: Uint8Array) => Uint8Array;
+ shaRmd160: (data: Uint8Array) => Uint8Array;
+}
+
+// Extend global this to include HASHES and Ecc
+declare global {
+ interface GlobalThis {
+ ecashlib: {
+ HASHES: EcashLibHashes;
+ Ecc: { new (): Ecc };
+ };
+ }
+}
diff --git a/modules/ecash-lib/package-lock.json b/modules/ecash-lib/package-lock.json
--- a/modules/ecash-lib/package-lock.json
+++ b/modules/ecash-lib/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ecash-lib",
- "version": "1.2.1",
+ "version": "1.2.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ecash-lib",
- "version": "1.2.1",
+ "version": "1.2.2",
"license": "MIT",
"dependencies": {
"b58-ts": "file:../b58-ts",
diff --git a/modules/ecash-lib/package.json b/modules/ecash-lib/package.json
--- a/modules/ecash-lib/package.json
+++ b/modules/ecash-lib/package.json
@@ -1,6 +1,6 @@
{
"name": "ecash-lib",
- "version": "1.2.1",
+ "version": "1.2.2",
"description": "Library for eCash transaction building",
"main": "./dist/indexNodeJs.js",
"browser": "./dist/indexBrowser.js",
diff --git a/modules/ecash-lib/src/ecc.ts b/modules/ecash-lib/src/ecc.ts
--- a/modules/ecash-lib/src/ecc.ts
+++ b/modules/ecash-lib/src/ecc.ts
@@ -14,8 +14,27 @@
schnorrSign(seckey: Uint8Array, msg: Uint8Array): Uint8Array;
}
+/** Uninitialized Ecc impl that throws an error asking for initWasm */
+export class EccBeforeWasm implements Ecc {
+ constructor() {
+ throw new Error('Ecc is not initialized, initWasm() must be called');
+ }
+
+ derivePubkey(_seckey: Uint8Array): Uint8Array {
+ throw new Error('Ecc is not initialized, initWasm() must be called');
+ }
+
+ ecdsaSign(_seckey: Uint8Array, _msg: Uint8Array): Uint8Array {
+ throw new Error('Ecc is not initialized, initWasm() must be called');
+ }
+
+ schnorrSign(_seckey: Uint8Array, _msg: Uint8Array): Uint8Array {
+ throw new Error('Ecc is not initialized, initWasm() must be called');
+ }
+}
+
/** Ecc implementation using WebAssembly */
-export let Ecc: { new (): Ecc };
+export let Ecc: { new (): Ecc } | { new (): EccBeforeWasm };
/** Dummy Ecc impl that always returns 0, useful for measuring tx size */
export class EccDummy implements Ecc {
@@ -34,4 +53,11 @@
export function __setEcc(ecc: { new (): Ecc }) {
Ecc = ecc;
+
+ Object.assign(globalThis, {
+ ecashlib: {
+ ...((globalThis as Record<string, any>).ecashlib || {}),
+ Ecc: ecc,
+ },
+ } as Partial<typeof globalThis>);
}
diff --git a/modules/ecash-lib/src/hash.ts b/modules/ecash-lib/src/hash.ts
--- a/modules/ecash-lib/src/hash.ts
+++ b/modules/ecash-lib/src/hash.ts
@@ -2,24 +2,39 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-interface EcashLibHashes {
- sha256: (data: Uint8Array) => Uint8Array;
- sha256d: (data: Uint8Array) => Uint8Array;
- shaRmd160: (data: Uint8Array) => Uint8Array;
-}
+import type { EcashLibHashes } from '../global';
let HASHES: EcashLibHashes;
export function sha256(data: Uint8Array): Uint8Array {
- return HASHES.sha256(data);
+ return (
+ globalThis as typeof globalThis & {
+ ecashlib: { HASHES: EcashLibHashes };
+ }
+ ).ecashlib.HASHES.sha256(data);
}
export function sha256d(data: Uint8Array): Uint8Array {
- return HASHES.sha256d(data);
+ return (
+ globalThis as typeof globalThis & {
+ ecashlib: { HASHES: EcashLibHashes };
+ }
+ ).ecashlib.HASHES.sha256d(data);
}
export function shaRmd160(data: Uint8Array): Uint8Array {
- return HASHES.shaRmd160(data);
+ return (
+ globalThis as typeof globalThis & {
+ ecashlib: { HASHES: EcashLibHashes };
+ }
+ ).ecashlib.HASHES.shaRmd160(data);
}
export function __setHashes(hashes: EcashLibHashes) {
HASHES = hashes;
+
+ Object.assign(globalThis, {
+ ecashlib: {
+ ...((globalThis as Record<string, any>).ecashlib || {}),
+ HASHES: hashes,
+ },
+ } as Partial<typeof globalThis>);
}
diff --git a/modules/ecash-lib/tsconfig.json b/modules/ecash-lib/tsconfig.json
--- a/modules/ecash-lib/tsconfig.json
+++ b/modules/ecash-lib/tsconfig.json
@@ -14,5 +14,5 @@
/* Type Checking */
"strict": true
},
- "include": ["src/**/*", "tests/**/*"]
+ "include": ["src/**/*", "tests/**/*", "global.d.ts"]
}

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 11:56 (3 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187737
Default Alt Text
D17464.id51960.diff (7 KB)

Event Timeline