everx-labs / ever-sdk-js

Javascript SDK for TVM blockchains (Everscale, TON, Venom, etc)
https://tonlabs.github.io/ever-sdk-js/
Apache License 2.0
96 stars 25 forks source link

Deno runtime support #501

Open awnion opened 1 year ago

awnion commented 1 year ago

Detail experiment can be found here: readme

I think it's pretty easy to add Deno support. Deno can work almost like web runtime with wasm. We just need to fix some hardcoded assumptions like fetch('/evernode.wasm') because this is too browser-specific.

  1. Right now the naive approach doesn't work yet. Consider:
import { TonClient } from "npm:@eversdk/core";
import { libWeb } from "npm:@eversdk/lib-web"; // or lib-node

TonClient.useBinaryLibrary(libWeb);

const client = new TonClient();
const { phrase } = await client.crypto.mnemonic_from_random({});
console.log(phrase);
client.close();

Will give us:

error: Could not resolve 'npm:@eversdk/lib-web'
  1. lib-node approach also doesn't work.

In short:

error: Uncaught TypeError: /root/.tonlabs/binaries/1/eversdk.node: undefined symbol: SSL_CTX_free

Seems like something with dynamic linking made for nodejs runtime. It feels easily fixable since Deno is made on Rust and Eversdk too.

UPD

  1. Workaround: https://github.com/awnion/example-ever-sdk-deno/blob/main/deno-custom-wasm-url.ts
import { TonClient } from "npm:@eversdk/core";
// require npm i @eversdk/lib-web
import { libWeb, libWebSetup } from "./node_modules/@eversdk/lib-web/index.js";

// require npm i @eversdk/lib-web
libWebSetup({
  disableSeparateWorker: true,
  binaryURL: new URL(
    "./node_modules/@eversdk/lib-web/eversdk.wasm",
    import.meta.url,
  ),
});

TonClient.useBinaryLibrary(libWeb);
// ------------------------^^^^^^
// here linter will complain but it's OK

const client = new TonClient();
const { phrase } = await client.crypto.mnemonic_from_random({});
console.log(phrase);
client.close();

Whilst it works it's not very convenient because we have to manually import index.js from node_modules. The main concern is that we use two different ways of distribution: 1) TonClient comes from npm: and we can't easily vendor it from node_modules since its internals link to each other node-js (or rather CommonJS) way. 2) And vice versa lib-web can be imported only via index.js directly and doesn't work with npm: deno-way.

The ideal solution would be to have libDeno (or rather libWasm / libWasi / etc) for server-side WASM + deno modules deployed on Deno

elasticLove1 commented 1 year ago

Working on it now)

awnion commented 1 year ago

Inside docker

If I try like this https://github.com/awnion/example-ever-sdk-deno/blob/main/sdk-deno-test.ts

Under docker image https://github.com/awnion/example-ever-sdk-deno/blob/main/sdk-deno-test.Dockerfile

IMAGE_TAG := sdk-deno-test

run:
    docker build --progress=plain -t $(IMAGE_TAG) -f sdk-deno-test.Dockerfile .
    docker run --rm -ti -v $$(pwd):/workdir $(IMAGE_TAG) deno run -A --unstable "./sdk-deno-test.ts"
make run

Throws error:

>>> 1.44.1
error: Uncaught {
  code: 25,
  message: "Unknown function: ",
  data: { core_version: "1.44.1" }
}
make: *** [run] Error 1

So it partially works, might be a minor problem


Mac m2 natively built deno+eversdk.deno form source

❯ deno run -A --unstable sdk-deno-test.ts
>>> 1.44.1
[1]    32033 segmentation fault  deno run -A --unstable sdk-deno-test.ts