Skip to content
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

Using lit-node-client-nodejs inside a Cloudflare Worker #14

Closed
spacesailor24 opened this issue Apr 17, 2024 · 8 comments
Closed

Using lit-node-client-nodejs inside a Cloudflare Worker #14

spacesailor24 opened this issue Apr 17, 2024 · 8 comments
Labels
question Further information is requested

Comments

@spacesailor24
Copy link

Description of the issue

From the user:

lit requires node's crypto library (unsuprisingly) which cloudflare workers have wrapped and exported individually. Workers do support the WebCrypto library fully I believe though, which Lit requires but it's getting it from node's crypto so it won't load.

Was just wondering if anybody had done any fancy bundling they could share to make it work.

I know Anson had it working on older versions of Lit

Additional context

No response

@spacesailor24 spacesailor24 added the question Further information is requested label Apr 17, 2024
@zach-is-my-name
Copy link

zach-is-my-name commented Apr 17, 2024

Hi. I'm the original author. I'd like to make this an official feature request if nobody minds...

Rationale: Making lit-node-client-nodejs compatible with the Cloudflare Workers platform would probably enable serving lit-node-client-nodejs in the most economical, scalable, and lowest latency way possible. https://developers.cloudflare.com/workers/platform/pricing/#example-pricing-standard-usage-model
(Dx is amazing as well)

@joshLong145
Copy link

@zach-is-my-name
we have just published v5.0.0 which removes a polyfill for crypto which should now allow you to import the cloudflare crypto package: https://developers.cloudflare.com/workers/runtime-apis/nodejs/crypto/

@zach-is-my-name
Copy link

zach-is-my-name commented Apr 26, 2024

Thanks @joshLong145. I spent the day yesterday with various GPTs trying to re-export Cloudflare's crypto to get it working with @lit-protocol/lit-node-client-nodejs@latest to no avail. Assigning Cloudflare's compatibility modules (crypto, buffer, etc) to the global scope to be picked up by all of the dependencies including Lit and its dependencies is eluding me.

/*Cloudflare Worker*/
import * as crypto from "node:crypto"
import * as LitJsSdk from "@lit-protocol/lit-node-client-nodejs";
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const litNodeClient = new LitJsSdk.LitNodeClientNodeJs({
      alertWhenUnauthorized: false,
      litNetwork: "cayenne",
    });

    const connected = await litNodeClient.connect();
		console.log(connected)


    return new Response('Hello World!');
  },
};
[~/tmp/twilight-field-ad91]$ wrangler dev
 ⛅️ wrangler 3.52.0
[wrangler:inf] Ready on http://localhost:32901
✘ [ERROR] Could not resolve "crypto"

    node_modules/@cosmjs/crypto/build/pbkdf2.js:39:83:
      39 │ ...ait Promise.resolve().then(() => __importStar(require("crypto")));
         ╵                                                          

  The package "crypto" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.


✘ [ERROR] Could not resolve "crypto"

    node_modules/@lit-protocol/nacl/src/lib/nacl.js:1167:25:
      1167 │         crypto = require('crypto');
           ╵                          

[~/tmp/twilight-field-ad91]$ head wrangler.toml
#:schema node_modules/wrangler/config-schema.json
name = "twilight-field-ad91"
main = "src/index.ts"
compatibility_date = "2024-04-19"
 compatibility_flags = [ "nodejs_compat" ]
# Automatically place your workloads in an optimal location to minimize latency.
# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure
# rather than the end user may result in better performance.
# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
# [placement]
[~/tmp/twilight-field-ad91]$

I made my test repo available. https://github.com/zach-is-my-name/twilight-field-ad91# npx wrangler dev should run it in locally in the Workers env

@joshLong145
Copy link

@zach-is-my-name
so it looks like cloudflare requires you to import with node: prefixing for their runtime to inject their custom modules.
A solution that might help you is to bundle with webpack targeting esm for Deno compatibility and utilize fallback resolvers to replace crypto with node:crypto im not quite sure if this will work but worth a try. Below is an example of how the fallback can be defined:

module.exports = {
  //...
  resolve: {
    fallback: {
        crypto: require.resolve('node:crypto')
    }
}

@zach-is-my-name
Copy link

zach-is-my-name commented Apr 27, 2024

Hi @joshLong145 ,
After exploring this a good deal I've come to understand the limitations of Cloudflare's runtime in more detail. Adapting any crypto app to run in Cloudflare's environment is going to be tricky. I was initially encouraged by Chris and Anson's earlier success with V1 of Lit. https://developer.litprotocol.com/v2/sdk/examples#cloudflare-x-lit

I don't know how they worked exactly, wasm perhaps?


Anyway here's my response to your suggestion:

Thank you for your suggestion regarding the use of node:crypto with Webpack's resolve.fallback. After further reflection and consideration, I realize there may be a fundamental issue with this approach due to the discrepancies between the environments during the Webpack build and Cloudflare's runtime.

While Cloudflare Workers do support a subset of Node.js's crypto module via the node:crypto compatibility layer, Webpack's resolution of this module during the build occurs in a traditional Node.js environment. This means it cannot accurately represent or utilize Cloudflare's specific runtime adaptations of node:crypto, which could lead to runtime errors or unexpected behavior once deployed.

Given this, I believe it might be beneficial to explore other avenues that could address these environment discrepancies more effectively. Perhaps we could consider:

Testing with Cloudflare-specific Tools: Utilizing tools designed to work closely with Cloudflare's runtime from the outset, ensuring compatibility without relying on traditional Node.js build tools.
Runtime Checks and Adaptations: Implementing checks within the application to dynamically load and handle cryptographic functions based on the detected environment, ensuring compatibility directly at runtime.
I would appreciate any further insights or suggestions you might have on how best to proceed given these constraints. Your expertise and further guidance would be invaluable as we look for a solution that ensures robust and error-free deployment on Cloudflare Workers.

Best regards,

Zach

@spacesailor24
Copy link
Author

Hey @zach-is-my-name just wanted to follow up on this: The team is interested in investigating the compatibility issues and a ticket has been created to track this. However, there is not ETA available at the time. I'll make sure to update you as I hear more about progress on this

@zach-is-my-name
Copy link

Much appreciated. I'm happy to close it if it's already being tracked internally.

@spacesailor24
Copy link
Author

Yes, it is!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants