-
Notifications
You must be signed in to change notification settings - Fork 18
[SBA-03] extract WASM functions from LNC into WasmManager class #132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
3de4eac to
515034d
Compare
4878338 to
a0489fb
Compare
2d53e9d to
8d6504a
Compare
96711f0 to
763f15d
Compare
41df1c5 to
f2f808f
Compare
763f15d to
13bd745
Compare
f2f808f to
bd9f16a
Compare
13bd745 to
bdca5e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR extracts WASM-related lifecycle, connection, and RPC logic from the LNC class into a new WasmManager class. The refactoring maintains the existing public API while improving maintainability and preparing for future session-based authentication features.
Key Changes:
- Created
WasmManagerclass to encapsulate all WASM operations, connection management, and RPC communication - Updated
LNCclass to delegate WASM operations toWasmManagerwhile preserving its public interface - Moved
lncGlobalreference fromlnc.tstowasmManager.tsfor better encapsulation
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| lib/wasmManager.ts | New class implementing WASM lifecycle, connection logic, and RPC communication |
| lib/wasmManager.test.ts | Comprehensive test suite for the new WasmManager class |
| lib/lnc.ts | Refactored to delegate WASM operations to WasmManager while maintaining public API |
| lib/lnc.test.ts | Updated tests to reflect delegation pattern and removed implementation detail assertions |
| test/utils/test-helpers.ts | Updated import path for lncGlobal reference |
| lib/index.ts | Exported WasmManager for external use |
| lib/index.test.ts | Added test coverage for WebAssembly polyfill functionality |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
bd9f16a to
169fb35
Compare
da2316c to
5bf01d8
Compare
5bf01d8 to
3167e15
Compare
jbrill
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! I've left quite a few comments (some of which may or may not be helpful). The code reads much cleaner 👏
| /** | ||
| * Waits until the WASM client is ready | ||
| */ | ||
| async waitTilReady(): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor issues:
- No immediate check — It always waits 500ms before the first check, even if isReady is already true.
- Magic numbers — 500 and 20 are hardcoded.
- If the callback takes time to execute, this might not actually measure the 10 seconds.
- No cancellation possible
Since waitForConnection has the same pattern, we could maybe abstract some of this:
private async pollUntil(
condition: () => boolean,
errorMessage: string,
timeout = 10_000
): Promise<void> {
const start = Date.now();
while (!condition()) {
if (Date.now() - start > timeout) {
throw new Error(errorMessage);
}
await new Promise(r => setTimeout(r, 500));
}
}
async waitTilReady(): Promise<void> {
await this.pollUntil(() => this.isReady, 'Failed to load the WASM client');
log.info('The WASM client is ready');
}
| * Disconnects from the proxy server | ||
| */ | ||
| disconnect(): void { | ||
| this.wasm.wasmClientDisconnect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove the listener we added in connect?
https://github.com/lightninglabs/lnc-web/pull/132/files#diff-d35515cfe8cd5410830da9527756c4638e092d394fd6c9f5ca5399578db9e37fR212
| /** | ||
| * Connects to the LNC proxy server | ||
| */ | ||
| async connect(credentialProvider?: CredentialProvider): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it makes sense to store our connections to ensure there are no race conditions when this is called twice:
private connectionPromise?: Promise<void>;
async connect(credentialProvider?: CredentialProvider): Promise<void> {
if (this.isConnected) return;
// Return existing connection attempt if in progress
if (this.connectionPromise) {
return this.connectionPromise;
}
this.connectionPromise = this.doConnect(credentialProvider);
try {
await this.connectionPromise;
} finally {
this.connectionPromise = undefined;
}
}
| */ | ||
| async run(): Promise<void> { | ||
| // Make sure the WASM client binary is downloaded first | ||
| if (!this.isReady) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would the check for downloaded be if (!this.result) {?
| * Downloads the WASM client binary | ||
| */ | ||
| async preload(): Promise<void> { | ||
| this.result = await WebAssembly.instantiateStreaming( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check if this.result already exists?
|
|
||
| this.go.argv = [ | ||
| 'wasm-client', | ||
| '--debuglevel=debug,GOBN=info,GRPC=info', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to have the debug level configurable?
| private setupWasmCallbacks(): void { | ||
| if (!this.wasm.onLocalPrivCreate) { | ||
| this.wasm.onLocalPrivCreate = (keyHex: string) => { | ||
| log.debug('local private key created: ' + keyHex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging the private keys seems like something we might not want to do 😨
| log.debug('local private key created: ' + keyHex); | ||
| if (this.credentialProvider) { | ||
| this.credentialProvider.localKey = keyHex; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth logging if the credential provider doesn't exist here.
| } | ||
| if (!this.wasm.onAuthData) { | ||
| this.wasm.onAuthData = (keyHex: string) => { | ||
| log.debug('auth data received: ' + keyHex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we doing anything on auth data? Is this just for debugging?
Summary
This PR moves almost all WASM-related lifecycle, connection, and RPC logic out of the main
LNCclass into a dedicatedWasmManager, while keeping the publicLNCAPI the same. The goal is to keepLNCsmall and focused as it grows with upcoming session-based auth and passkey features, so new behavior can be added without turningLNCinto an unmaintainable “god class.” These changes build on the groundwork from #130 and #131 as part of the Session-Based Authentication & Passkeys work.Technical Notes
LNCfocused and maintainable: As we add more auth/session logic, the mainLNCclass would otherwise accumulate a lot of low-level WASM, connection, and RPC details; pushing those concerns intoWasmManagerkeepsLNCcloser to a thin façade over the APIs.Steps to Test
Run the unit tests (including the new
WasmManagertests and updatedLNCtests):yarn testBuild the library to ensure the production bundle still compiles correctly:
Related Issues & Pull Requests
Depends on: