Skip to content

Commit

Permalink
Add @web-solc/react package
Browse files Browse the repository at this point in the history
  • Loading branch information
gnidan committed Jul 10, 2024
1 parent d8778d5 commit 44799c5
Show file tree
Hide file tree
Showing 10 changed files with 510 additions and 22 deletions.
1 change: 0 additions & 1 deletion README.md

This file was deleted.

114 changes: 114 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# web-solc monorepo

This monorepo contains two packages that provide Solidity compilation
capabilities for web environments:

1. [web-solc](./packages/web-solc/README.md): A package for running specific versions of solc in the browser using web workers.
2. [@web-solc/react](./packages/react/README.md): React bindings around web-solc

## web-solc

[![npm version](https://img.shields.io/npm/v/web-solc)](https://www.npmjs.com/package/web-solc)

The `web-solc` package allows you to run specific versions of the Solidity
compiler (solc) in the browser using web workers. It supports arbitrary
Solidity compilation using the
[Compiler Input and Output JSON](https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description)
format.

### Usage

```typescript
import { fetchSolc } from "web-solc";

const { compile, stopWorker } = await fetchSolc("^0.8.25");

const { contracts } = await compile({
language: "Solidity",
sources: {
"test.sol": {
content: "pragma solidity ^0.8.0; contract Test {}"
}
},
settings: {
outputSelection: {
"*": {
"*": ["*"]
}
}
}
});

// Don't forget to cleanup the running Worker when done
stopWorker();
```

For more details, see the [web-solc README](./packages/web-solc/README.md).

## @web-solc/react

[![npm version](https://img.shields.io/npm/v/%40web-solc%2Freact)](https://www.npmjs.com/package/@web-solc/react)

The `@web-solc/react` package provides React bindings for using the Solidity
compiler in browser environments. It offers a `useWebSolc()` hook and a
`<WebSolcProvider>` component for easy integration with React
applications.

### Usage

```tsx
import { WebSolcProvider, useWebSolc } from "@web-solc/react";
import type { CompilerInput, CompilerOutput } from "web-solc";

function App() {
return (
<WebSolcProvider>
<CompilationComponent />
</WebSolcProvider>
);
}

function CompilationComponent({ compilerInput }: { compilerInput: CompilerInput }) {
const solc = useWebSolc("^0.8.25");

if (!solc) {
return <>Loading solc...</>;
}

const compile = async () => {
try {
const output: CompilerOutput = await solc.compile(compilerInput);
console.log("Compilation output:", output);
} catch (error) {
console.error("Compilation error:", error);
}
};

return <button onClick={compile}>Compile</button>;
}
```

For more details, see the [@web-solc/react README](./packages/react/README.md).

## Example Vite App

This repository includes a sample webapp that demonstrates Solidity compilation
inside the browser. You can find it in the
[`./packages/example/`](./packages/example/) directory.

## Installation

To use these packages in your project, you can install them via npm:

```console
npm install --save web-solc @web-solc/react
```

## Contributing

Contributions are welcome! Please feel free to submit a pull request.

## License

This project is licensed under the MIT License - see the [LICENSE](./LICENSE)
file for details.
3 changes: 2 additions & 1 deletion bin/start
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env sh

# Run the commands with concurrently
concurrently --names=web-solc,example\
concurrently --names=web-solc,react,example\
"cd ./packages/web-solc && yarn prepare --watch" \
"cd ./packages/react && yarn prepare --watch" \
"cd ./packages/example && yarn dev"
1 change: 1 addition & 0 deletions packages/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@web-solc/react": "^0.1.0-0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"web-solc": "^0.5.0"
Expand Down
18 changes: 15 additions & 3 deletions packages/example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { useState } from "react";
import "./App.css";

import { fetchSolc } from "web-solc";
import { WebSolcProvider, useWebSolc } from "@web-solc/react";

export default function App() {
export function Example() {
const solc = useWebSolc("^0.8.25");
const [output, setOutput] = useState("");

if (!solc) {
return <>Loading...</>;
}

const compile = async () => {
try {
const solc = await fetchSolc("^0.8.0");
const result = await solc.compile({
language: "Solidity",
sources: {
Expand Down Expand Up @@ -38,3 +42,11 @@ export default function App() {
</div>
)
}

export default function App() {
return (
<WebSolcProvider>
<Example />
</WebSolcProvider>
)
}
2 changes: 2 additions & 0 deletions packages/react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
node_modules
116 changes: 116 additions & 0 deletions packages/react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# @web-solc/react

[![npm version](https://img.shields.io/npm/v/%40web-solc%2Freact)](https://www.npmjs.com/package/@web-solc/react)

This package provides React bindings for using the Solidity compiler (`solc`)
in browser environments.

## Installation

```console
npm install --save @web-solc/react
```

or

```console
yarn add @web-solc/react
```

## Usage

### `useWebSolc()` hook

The `useWebSolc(versionRange: string)` hook provides a straightforward method
for fetching and running the Solidity compiler client-side within a React
application.

This hook fetches the list of Solidity compiler versions and fetches the
latest release that satisfies the [semantic versioning](https://semver.org)
constraints specified by `versionRange`.

This hook relies on the use of a shared pool that must be instantiated via the
`<WebSolcProvider>` component, this package's other main export.


```tsx
import { useState } from "react";

import type { CompilerInput, CompilerOutput } from "web-solc";

import { useWebSolc } from "@web-solc/react";

export interface Props {
compilerInput: CompilerInput;
}

export default function MyComponent({
compilerInput
}) {
const solc = useWebSolc("^0.8.25");
if (!solc) {
return <>Loading solc...</>;
}

const [compilation, setCompilation] = useState<CompilerOutput | undefined>();

const compile = async () => {
try {
setCompilation(
await solc.compile(compilerInput)
);
} catch (error) {
console.error("Compilation error: ", error);
}
}

return (
<div>
<button onClick={compile}>Compile</button>
{compilation && <pre>{JSON.stringify(compilation, null, 2)}</pre>}
</div>
);
}
```

### `<WebSolcProvider>` component

Because solc-js only runs in the browser inside a Web Worker, it becomes
necessary to handle stopping these when they are no longer needed.

This is handled via the use of the `<WebSolcProvider>` component, whose
behavior includes performing the necessary cleanup when _it_ unmounts.

This component **must** wrap any children or other descendent components in
order for their being able to access the `useWebSolc()` hook.

```tsx
import { WebSolcProvider } from "@web-solc/react";

export default function App() {
return (
// ... other context providers
<WebSolcProvider>
{/* ... children */}
</WebSolcProvider>
);
}
```

#### Customizing compiler source repository

The **web-solc** allows customizing the base URL for obtaining the list of
available compiler versions and the compiler emscripten binaries themselves.
It is possible to specify a mirror via the `repository` prop:

```tsx
import { WebSolcProvider } from "@web-solc/react";

export default function App() {
return (
<WebSolcProvider repository={{ baseUrl: "https://custom.solc.builds" }}>
{/* ... children */}
</WebSolcProvider>
);
}
```
32 changes: 32 additions & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@web-solc/react",
"version": "0.1.0-0",
"description": "In-browser Solidity compilation for React projects",
"type": "module",
"main": "./dist/src/index.jsx",
"types": "./dist/src/index.d.ts",
"author": "g. nicholas d'andrea <[email protected]>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/gnidan/web-solc.git",
"directory": "packages/react"
},
"scripts": {
"prepare": "tsc"
},
"devDependencies": {
"@types/node": "^20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/semver": "^7.5.8",
"typescript": "^5.5.3"
},
"dependencies": {
"react": "^18.3.1",
"web-solc": "^0.5.0"
},
"publishConfig": {
"access": "public"
}
}
Loading

0 comments on commit 44799c5

Please sign in to comment.