Skip to content

Latest commit

 

History

History
144 lines (107 loc) · 4.51 KB

File metadata and controls

144 lines (107 loc) · 4.51 KB

@evm-effect/solc

Effect-TS service for compiling Solidity using the standard Solidity compiler JSON interface. The same Solc tag is provided in two ways: on Node via the official solc package, and in the browser / Next.js via a prebundled worker and a small App Router API.

Which implementation should I use?

Use case Import What it does
Node, scripts, servers @evm-effect/solc/node Uses solc directly (compile, loadRemoteVersion). No worker bundle or Next route.
Browser / Next.js, client-side compile @evm-effect/solc/next your app serves worker.js and compiler binaries through nextWorkerApi. Use when the compiler must run in a Worker on the client.

Installation

npm add @evm-effect/solc effect @effect/platform

The examples below use FetchHttpClient.layer from @effect/platform to satisfy the HttpClient requirement of Solc. Align effect and @effect/platform versions with your app (this repo’s catalog uses compatible ^0.9x / ^3.x ranges).

Solc.compile

The Solc service is a Context.Tag whose compile method takes the standard JSON CompilerInput and an optional second argument for the compiler build:

readonly compile: (
  input: CompilerInput,
  options?: {
    solidityVersion?: string;
  },
) => Effect.Effect<
  CompilerOutput.CompilerOutput,
  SolcWorkerError,
  HttpClient.HttpClient
>;

Pass solidityVersion when you need a specific release (for example "latest" or a version from the binary list).

yield* solc.compile(compilerInput, { solidityVersion: "0.8.26" });

Next.js (App Router)

API route

Add a catch-all route so the package can serve the bundled worker and proxy compiler builds from binaries.soliditylang.org.

Create src/app/api/solc/[...params]/route.ts

export { nextWorkerApi as GET } from "@evm-effect/solc/next";

This handler responds to:

  • worker.js — prebundled worker script (module Worker entry).
  • bin/{version} — compiler build for that version, adapted so the worker can import() it.

Client usage

Import the preconfigured SolcNextLayer to use it with the default options.

If your nextWorkerApi route is not at app/api/solc/..., pass const SolcNextLayer = setupSolcNextLayer({ workerApiUrl: "custom/path" }) instead.

import { FetchHttpClient } from "@effect/platform";
import { Effect } from "effect";
import { Solc } from "@evm-effect/solc";
import { SolcNextLayer } from "@evm-effect/solc/next";

const program = Effect.gen(function* () {
  const solcWorker = yield* Solc;
  const result = yield* solcWorker.compile({
    language: "Solidity",
    sources: {
      "Hello.sol": {
        content: `
          // SPDX-License-Identifier: MIT
          pragma solidity ^0.8.3;

          contract Counter {
              uint public count;

              function get() public view returns (uint) {
                  return count;
              }

              function inc() public {
                  count += 1;
              }

              function dec() public {
                  count -= 1;
              }
          }
          `,
      },
    },
    settings: {
      outputSelection: {
        "*": {
          "*": ["*"],
        },
      },
    },
  });
  return result;
}).pipe(Effect.provide([SolcNextLayer, FetchHttpClient.layer]));

Effect.runPromise(program);

Node

Use SolcNodeLayer when you run in Node, this will wrap solc package.

import { FetchHttpClient } from "@effect/platform";
import { Effect } from "effect";
import { Solc } from "@evm-effect/solc";
import { SolcNodeLayer } from "@evm-effect/solc/node";

const program = Effect.gen(function* () {
  const solc = yield* Solc;
  return yield* solc.compile({
    language: "Solidity",
    sources: {
      "Hello.sol": { content: "pragma solidity ^0.8.3; contract C {}" },
    },
    settings: {
      outputSelection: { "*": { "*": ["*"] } },
    },
  });
}).pipe(Effect.provide([SolcNodeLayer, FetchHttpClient.layer]));

Effect.runPromise(program);

License

MIT — see the repository root LICENSE.