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

Make easy the WASM artifact load from nucypher-core #120

Closed
manumonti opened this issue Nov 29, 2022 · 5 comments
Closed

Make easy the WASM artifact load from nucypher-core #120

manumonti opened this issue Nov 29, 2022 · 5 comments
Assignees
Labels

Comments

@manumonti
Copy link
Member

manumonti commented Nov 29, 2022

Related to #119.

When we try to add as a dependency nucypher-ts into a web app, this loads a WASM artifact from nucypher-core package. This requires having a bundler that understands what WASM is.

The objective of this issue is to make this as easy as possible. How to do it is a matter of research.

One option could be to pack wasm-pack artifacts (nucypher-core WASM) into a multi-platform JS package. This is how we're doing at the moment.

@manumonti
Copy link
Member Author

@piotr-roslaniec could you please review this description and correct me and/or complete the information if needed? 🙏

@piotr-roslaniec piotr-roslaniec added the enhancement New feature or request label Nov 29, 2022
@manumonti manumonti mentioned this issue Nov 29, 2022
@piotr-roslaniec
Copy link
Contributor

piotr-roslaniec commented Dec 13, 2022

Explore the possibility of using a --target web target for nucypher-core. Another possible approach is to use a bundler that understands how to inline WASM into the bundle as a base64 encoded string (1, 2).

@piotr-roslaniec
Copy link
Contributor

This is an ongoing issue for some of our users. Related: rustwasm/wasm-pack#313

@theref
Copy link
Contributor

theref commented May 18, 2023

Some progress has been made on this issue. The builder we have been using makes it difficult to fix these issues, switching to esbuild makes them easy.
To reproduce, add these lines to package.json

// scripts
    "build:bundle": "node esbuild.config.js"
// devDependencies
    "esbuild": "^0.17.19",
    "esbuild-plugin-wasm": "^1.1.0",

Add a new file, esbuild.config.js:

const esbuild = require("esbuild");
const { wasmLoader } = require('esbuild-plugin-wasm')

esbuild
    .build({
        entryPoints: ["src/index.ts"],
	outfile: "build/bundle/nucypher-ts.js",
	target: "esnext",
	format: "esm",
        bundle: true,
        minify: true,
	supported: {
          'top-level-await': true
        },
	plugins: [
            wasmLoader({mode: "embedded"})
        ]
    })
    .catch(() => process.exit(1));

we can then run yarn build and a new folder will be created at build/bundle

We need a test.html file. Notice that nucypher-ts is importing from the new, local build/bundle:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Untitled</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <!--
    JSPM Generator Import Map
    Edit URL: https://generator.jspm.io/#U21hYGBkDM0rySzJSU1hcMgrTa4syEgt0ocxdEuKHQz1DPQMdJNSSxL1DAETe7+vMQA
  -->
   <script type="importmap">
  {
    "imports": {
      "@nucypher/nucypher-ts": "/build/bundle/nucypher-ts.js",
      "@nucypher/nucypher-core": "https://esm.sh/*@nucypher/nucypher-core@0.4.0/pkg-bundler/nucypher_core_wasm.js/index.js"
    },
    "scopes": {
      "https://esm.sh/": {
        "@ethersproject/abi": "https://esm.sh/*@ethersproject/abi@5.7.0/lib.esm/index.js",
        "@ethersproject/abstract-provider": "https://esm.sh/*@ethersproject/abstract-provider@5.7.0/lib.esm/index.js",
        "@ethersproject/abstract-signer": "https://esm.sh/*@ethersproject/abstract-signer@5.7.0/lib.esm/index.js",
        "@ethersproject/address": "https://esm.sh/*@ethersproject/address@5.7.0/lib.esm/index.js",
        "@ethersproject/base64": "https://esm.sh/*@ethersproject/base64@5.7.0/lib.esm/index.js",
        "@ethersproject/basex": "https://esm.sh/*@ethersproject/basex@5.7.0/lib.esm/index.js",
        "@ethersproject/bignumber": "https://esm.sh/*@ethersproject/bignumber@5.7.0/lib.esm/index.js",
        "@ethersproject/bytes": "https://esm.sh/*@ethersproject/bytes@5.7.0/lib.esm/index.js",
        "@ethersproject/constants": "https://esm.sh/*@ethersproject/constants@5.7.0/lib.esm/index.js",
        "@ethersproject/contracts": "https://esm.sh/*@ethersproject/contracts@5.7.0/lib.esm/index.js",
        "@ethersproject/hash": "https://esm.sh/*@ethersproject/hash@5.7.0/lib.esm/index.js",
        "@ethersproject/hdnode": "https://esm.sh/*@ethersproject/hdnode@5.7.0/lib.esm/index.js",
        "@ethersproject/json-wallets": "https://esm.sh/*@ethersproject/json-wallets@5.7.0/lib.esm/index.js",
        "@ethersproject/keccak256": "https://esm.sh/*@ethersproject/keccak256@5.7.0/lib.esm/index.js",
        "@ethersproject/logger": "https://esm.sh/*@ethersproject/logger@5.7.0/lib.esm/index.js",
        "@ethersproject/networks": "https://esm.sh/*@ethersproject/networks@5.7.1/lib.esm/index.js",
        "@ethersproject/pbkdf2": "https://esm.sh/*@ethersproject/pbkdf2@5.7.0/lib.esm/index.js",
        "@ethersproject/properties": "https://esm.sh/*@ethersproject/properties@5.7.0/lib.esm/index.js",
        "@ethersproject/providers": "https://esm.sh/*@ethersproject/providers@5.7.2/lib.esm/index.js",
        "@ethersproject/random": "https://esm.sh/*@ethersproject/random@5.7.0/lib.esm/index.js",
        "@ethersproject/rlp": "https://esm.sh/*@ethersproject/rlp@5.7.0/lib.esm/index.js",
        "@ethersproject/sha2": "https://esm.sh/*@ethersproject/sha2@5.7.0/lib.esm/index.js",
        "@ethersproject/signing-key": "https://esm.sh/*@ethersproject/signing-key@5.7.0/lib.esm/index.js",
        "@ethersproject/solidity": "https://esm.sh/*@ethersproject/solidity@5.7.0/lib.esm/index.js",
        "@ethersproject/strings": "https://esm.sh/*@ethersproject/strings@5.7.0/lib.esm/index.js",
        "@ethersproject/transactions": "https://esm.sh/*@ethersproject/transactions@5.7.0/lib.esm/index.js",
        "@ethersproject/units": "https://esm.sh/*@ethersproject/units@5.7.0/lib.esm/index.js",
        "@ethersproject/wallet": "https://esm.sh/*@ethersproject/wallet@5.7.0/lib.esm/index.js",
        "@ethersproject/web": "https://esm.sh/*@ethersproject/web@5.7.1/lib.esm/index.js",
        "@ethersproject/wordlists": "https://esm.sh/*@ethersproject/wordlists@5.7.0/lib.esm/index.js",
        "aes-js": "https://esm.sh/*aes-js@3.1.2/index.js",
        "axios": "https://esm.sh/*axios@0.21.4/index.js",
        "bech32": "https://esm.sh/*bech32@2.0.0/dist/index.js",
        "bn.js": "https://esm.sh/*bn.js@5.2.1/lib/bn.js/index.js",
        "call-bind/callBound": "https://esm.sh/*call-bind@1.0.2/callBound",
        "ethers": "https://esm.sh/*ethers@5.7.2/lib.esm/index.js",
        "function-bind": "https://esm.sh/*function-bind@1.1.1/index/index.js",
        "get-intrinsic": "https://esm.sh/*get-intrinsic@1.2.0",
        "hash.js": "https://esm.sh/*hash.js@1.1.7/lib/hash.js/index.js",
        "inherits": "https://esm.sh/*inherits@2.0.4/inherits_browser.js/index.js",
        "joi": "https://esm.sh/*joi@17.9.2/dist/joi-browser.min.js/index.js",
        "js-sha3": "https://esm.sh/*js-sha3@0.8.0/src/sha3.js/index.js",
        "minimalistic-assert": "https://esm.sh/*minimalistic-assert@1.0.1/index.js",
        "object-inspect": "https://esm.sh/*object-inspect@1.12.3/index.js",
        "qs": "https://esm.sh/*qs@6.11.1/lib/index.js",
        "scrypt-js": "https://esm.sh/*scrypt-js@3.0.1/scrypt.js/index.js",
        "side-channel": "https://esm.sh/*side-channel@1.0.4"
      }
    }
  }
  </script>
  
  <!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support (Safari 16.3) -->
  <script async src="https://ga.jspm.io/npm:es-module-shims@1.5.1/dist/es-module-shims.js" crossorigin="anonymous"></script>
  
  <script type="module">
	import { Cohort, Conditions } from '@nucypher/nucypher-ts';

	const config = {
	  threshold: 3,
	  shares: 5,
	  porterUri: 'https://porter-tapir.nucypher.community',
	};
	const newCohort = await Cohort.create(config);
  console.log(newCohort);
  </script>
</body>

A simple python http server server.py:

from http.server import HTTPServer, SimpleHTTPRequestHandler

class MyRequestHandler(SimpleHTTPRequestHandler):
    # Set the MIME type for .wasm files to application/wasm
    MIMETypes = {
        ".wasm": "application/wasm"
    }

# Start the HTTP server on port 8000
httpd = HTTPServer(('localhost', 8000), MyRequestHandler)
httpd.serve_forever()

Then run python3 server.py and navigate to test.html. In the console you should see the 5 Ursula addresses of the Cohort. Thanks @s-cork for your help with this.

@piotr-roslaniec
Copy link
Contributor

Closed by #299

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Completed
Development

Successfully merging a pull request may close this issue.

4 participants