Skip to content

Commit

Permalink
Merge pull request #13 from OpenZeppelin/main
Browse files Browse the repository at this point in the history
Release to wizard
  • Loading branch information
MCarlomagno authored Dec 4, 2024
2 parents e87118a + fb6ffbe commit 84c8b5e
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 12 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@remixproject/plugin-utils": "^0.3.38",
"@sveltejs/adapter-netlify": "^4.3.6",
"bootstrap": "^5.3.3",
"ethers": "^6.13.4"
"ethers": "^6.13.4",
"solc": "^0.8.28"
}
}
57 changes: 57 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ declare global {
declare interface Window {
ethereum?: import('ethers').Eip1193Provider & import('ethers').BrowserProvider;
}

// solc does not have a type definition file.
declare module 'solc' {
export function compile(input: string, opts?: any): any;
}
11 changes: 11 additions & 0 deletions src/lib/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { CreateApprovalProcessRequest } from "./models/approval-process";
import type { Credentials } from "./models/auth";
import type { DeployContractRequest, UpdateDeploymentRequest } from "./models/deploy";
import type { CompilerInput } from "./models/solc";

class ApiClient {
credentials: Credentials | null = null;
Expand Down Expand Up @@ -72,6 +73,16 @@ class ApiClient {

return response.json();
}

async compile(input: CompilerInput) {
const response = await fetch("/compiler", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ input }),
});

return response.json();
}
}

export const API = new ApiClient();
35 changes: 35 additions & 0 deletions src/lib/models/solc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export type CompilerInput = {
/**
* The language, currently only Solidity is supported.
*/
language: string;
/**
* Name of the file and the content of the file.
* e.g. { 'test.sol': { content: 'contract C { function f() public { L.f(); } }' } }
*/
sources: ContractSources;
/**
* Settings for the compiler.
* e.g. { outputSelection: { '*': { '*': ['*'] } }"
*/
settings: {
outputSelection: Record<string, Record<string, string[]>>;
};
};

export type ContractSources = {
[source: string]: { content: string };
};

export function buildCompilerInput(sources: ContractSources): CompilerInput {
return {
sources,
language: 'Solidity',
settings: {
outputSelection: {
'*': { '*': ['*'] }
}
}
};
}

27 changes: 27 additions & 0 deletions src/lib/wizard/components/Configure.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts">
import { API } from "$lib/api";
import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
import { wizardState } from "../state.svelte";
let compilationResult: any;
async function compile() {
if (!wizardState.sources) return;
compilationResult = await API.compile(buildCompilerInput(wizardState.sources));
}
function getMainContractName(sources?: ContractSources) {
if (!sources) return '';
// The first name that is not a dependency
return Object.keys(sources).find(name => !name.startsWith('@'));
}
</script>

<p>
Contract to compile: {getMainContractName(wizardState.sources)}

<button onclick={compile} >
Compile
</button>
</p>
18 changes: 17 additions & 1 deletion src/lib/wizard/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
import type { ContractSources } from "../models/solc";
import { wizardState } from "./state.svelte";

export interface DefenderDeployMessage {
kind: 'oz-wizard-defender-deploy';
sources: ContractSources;
}

export const initWizardPlugin = () => {
// when users configure a contract, the plugin gets the results.
// listenToContracts();
listenToContracts();
}

function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent<DefenderDeployMessage>) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
wizardState.sources = e.data.sources;
}
});
}
5 changes: 5 additions & 0 deletions src/lib/wizard/state.svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { ContractSources } from "../models/solc";

export const wizardState = $state<{ sources: ContractSources | undefined }>({
sources: undefined,
});
15 changes: 6 additions & 9 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,17 @@
// assumes that when in dev mode and
// the ancestor origin is localhost, we are in the wizard
if (dev && ancestorOrigin.includes("localhost")) {
parent = 'wizard';
return;
return parent = 'wizard';
}
if (ancestorOrigin.includes("remix.ethereum")) {
parent = 'remix';
return initRemixPlugin();
if (ancestorOrigin.includes("wizard.openzeppelin")) {
return parent = 'wizard';
}
if (ancestorOrigin.includes("wizard.openzeppelin")) {
parent = 'wizard';
// TODO: init wizard plugin
return;
if (ancestorOrigin.includes("remix.ethereum")) {
return parent = 'remix';
}
});
</script>

Expand Down
19 changes: 19 additions & 0 deletions src/routes/compiler/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { CompilerInput } from "$lib/models/solc";
import { json } from '@sveltejs/kit';
import { SolidityCompiler } from "./compiler";
import { attempt } from "$lib/utils/attempt";


export async function POST({ request }: { request: Request }) {
const { input }: { input: CompilerInput } = await request.json();

const compiler = new SolidityCompiler();

const [output, error] = await attempt(() => JSON.parse(compiler.compile(input)));

if (error) {
return json({ success: false, error: error.msg });
}

return json({ success: true, data: { output } });
}
20 changes: 20 additions & 0 deletions src/routes/compiler/compiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import solc from 'solc';

import type { ContractSources } from "$lib/models/solc";
import type { CompilerInput } from "$lib/models/solc";

export class SolidityCompiler {
getContent(path: string, contents: ContractSources) {
if (contents[path]) {
return contents[path];
}
return { error: 'File not found' };
}

compile(input: CompilerInput, contents?: ContractSources) {
const shouldFindImports = contents !== undefined;
const findImports = (path: string) => shouldFindImports ? this.getContent(path, contents) : undefined;
const output = solc.compile(JSON.stringify(input), shouldFindImports ? { import: findImports } : undefined);
return output;
}
}
4 changes: 4 additions & 0 deletions src/routes/remix.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script lang="ts">
import { onMount } from "svelte";
import { initRemixPlugin } from "$lib/remix";
import { globalState } from "$lib/remix/state/state.svelte";
import Setup from "$lib/remix/components/Setup.svelte";
import Network from "$lib/remix/components/Network.svelte";
Expand Down Expand Up @@ -48,6 +50,8 @@
return false;
});
onMount(initRemixPlugin);
</script>

<p>
Expand Down
8 changes: 7 additions & 1 deletion src/routes/wizard.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<script lang="ts">
import { initWizardPlugin } from "$lib/wizard";
import { onMount } from "svelte";
import Configure from "$lib/wizard/components/Configure.svelte";
onMount(initWizardPlugin);
</script>

<p>Defender Deploy in Wizard</p>
<Configure />

0 comments on commit 84c8b5e

Please sign in to comment.