From 6a4290da32d075eadaba384b87bf18ecff9cdd04 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Wed, 26 Feb 2025 23:35:12 +0200 Subject: [PATCH 01/16] make it work again in Deno 2, sync with upstream solc-js code --- .gitignore | 1 + README.md | 2 +- bindings.ts | 273 ----------------------------------- bindings/compile.ts | 211 +++++++++++++++++++++++++++ bindings/core.ts | 151 +++++++++++++++++++ bindings/helpers.ts | 50 +++++++ bindings/index.ts | 20 +++ deno.json | 5 + deno.lock | 16 +- download.ts | 8 +- download_test.ts | 16 +- examples/erc20/mod.ts | 8 +- examples/with-library/mod.ts | 4 +- mod.ts | 6 +- mod_test.ts | 6 +- types.ts | 5 +- 16 files changed, 484 insertions(+), 298 deletions(-) delete mode 100644 bindings.ts create mode 100644 bindings/compile.ts create mode 100644 bindings/core.ts create mode 100644 bindings/helpers.ts create mode 100644 bindings/index.ts diff --git a/.gitignore b/.gitignore index 55ea131..3576cb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.js +*.cjs coverage* \ No newline at end of file diff --git a/README.md b/README.md index f26ba09..602fb0c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ import { createRequire } from 'node:module' // Download latest Solidity compiler await download() -const solc = wrapper(createRequire(import.meta.url)('./soljson.js')) +const solc = wrapper(createRequire(import.meta.url)('./soljson.cjs')) const MyToken = await Deno.readTextFile('./MyToken.sol') const ERC20 = await Deno.readTextFile('./ERC20.sol') diff --git a/bindings.ts b/bindings.ts deleted file mode 100644 index 0b8190b..0000000 --- a/bindings.ts +++ /dev/null @@ -1,273 +0,0 @@ -/** - * Original source code: https://github.com/ethereum/solc-js/blob/master/bindings/core.ts - */ - -import { isNil } from './common.ts' -import type { Alloc, License, Reset, SolJson, Version } from './deps.ts' -import type { Callbacks, CoreBindings } from './types.ts' - -function bindSolcMethod( - solJson: SolJson, - method: string, - returnType: string | null, - args: string[], - defaultValue?: ((...args: unknown[]) => void) | null, -) { - if (isNil((solJson as SolJson & { [method: string]: unknown })[`_${method}`]) && defaultValue !== undefined) { - return defaultValue - } - - return solJson.cwrap(method, returnType, args) as (...args: unknown[]) => void -} - -function bindSolcMethodWithFallbackFunc( - solJson: SolJson, - method: string, - returnType: string | null, - args: string[], - fallbackMethod: string, - finalFallback: (() => void) | undefined = undefined, -) { - const methodFunc = bindSolcMethod(solJson, method, returnType, args, null) - - if (!isNil(methodFunc)) { - return methodFunc - } - - return bindSolcMethod(solJson, fallbackMethod, returnType, args, finalFallback) -} - -function bindAlloc(solJson: SolJson) { - const allocBinding = bindSolcMethod( - solJson, - 'solidity_alloc', - 'number', - ['number'], - null, - ) - - // the fallback malloc is not a cwrap function and should just be returned - // directly in-case the alloc binding could not happen. - if (isNil(allocBinding)) { - return solJson._malloc - } - - return allocBinding -} -const bindVersion = (solJson: SolJson) => - bindSolcMethodWithFallbackFunc( - solJson, - 'solidity_version', - 'string', - [], - 'version', - ) - -function bindLicense(solJson: SolJson) { - return bindSolcMethodWithFallbackFunc( - solJson, - 'solidity_license', - 'string', - [], - 'license', - () => { - }, - ) -} - -function bindReset(solJson: SolJson) { - return bindSolcMethod( - solJson, - 'solidity_reset', - null, - [], - null, - ) -} - -function unboundCopyToCString(solJson: SolJson, alloc: Alloc, str: string, ptr: number) { - const length = solJson.lengthBytesUTF8(str) - - const buffer = alloc(length + 1) - - solJson.stringToUTF8(str, buffer, length + 1) - solJson.setValue(ptr, buffer, '*') -} - -function unboundCopyFromCString(solJson: SolJson, ptr: number) { - const copyFromCString = solJson.UTF8ToString - return copyFromCString(ptr) -} - -function unboundAddFunction(solJson: SolJson, func: (...args: unknown[]) => unknown, signature?: string) { - return (solJson.addFunction || solJson.Runtime.addFunction)(func, signature) -} - -function unboundRemoveFunction(solJson: SolJson, ptr: number) { - return (solJson.removeFunction || solJson.Runtime.removeFunction)(ptr) -} - -const setupCore = (solJson: SolJson) => { - const core = { - alloc: bindAlloc(solJson) as Alloc, - license: bindLicense(solJson) as License, - version: bindVersion(solJson) as Version, - reset: bindReset(solJson) as Reset, - } - - const helpers = { - addFunction: unboundAddFunction.bind(this, solJson), - removeFunction: unboundRemoveFunction.bind(this, solJson), - - copyFromCString: unboundCopyFromCString.bind(this, solJson), - - copyToCString: unboundCopyToCString.bind(this, solJson, core.alloc) as unknown as ( - str: string, - ptr: number, - ) => string, - } - - return { - ...core, - ...helpers, - } -} - -const bindCompileJson = (solJson: SolJson) => - bindSolcMethod( - solJson, - 'compileJSON', - 'string', - ['string', 'number'], - null, - ) - -function wrapCallbackWithKind( - coreBindings: CoreBindings, - callback: (arg1: string, arg2: string) => { contents: string; error: string }, -) { - if (typeof callback !== 'function') throw new Error('Invalid callback specified.') - - return function (context: number, kind: number, data: number, contents: number, error: number): void { - // Must be a null pointer. - if (context !== 0) throw new Error('Callback context must be null.') - const result = callback(coreBindings.copyFromCString(kind), coreBindings.copyFromCString(data)) - if (typeof result.contents === 'string') { - coreBindings.copyToCString(result.contents, contents) - } - if (typeof result.error === 'string') { - coreBindings.copyToCString(result.error, error) - } - } -} - -// calls compile() with args || cb -function runWithCallbacks( - coreBindings: CoreBindings, - callbacks: Callbacks = {}, - compile: (...args: unknown[]) => void, - args: (number | null)[], -) { - let readCallback = callbacks.import - if (readCallback === undefined) { - readCallback = function () { - return { - error: 'File import callback not supported', - } - } - } - - const singleCallback = wrapCallbackWithKind(coreBindings, (kind: string, data: string) => { - if (kind === 'source') { - return readCallback!(data)! - } else if (kind === 'smt-query') { - return smtSolverCallback!(data)! - } else { - throw new Error('Invalid callback kind specified.') - } - }) - // After 0.6.x multiple kind of callbacks are supported. - let smtSolverCallback = callbacks.smtSolver - if (smtSolverCallback === undefined) { - smtSolverCallback = function () { - return { - error: 'SMT solver callback not supported', - } - } - } - - const cb = coreBindings.addFunction(singleCallback, 'viiiii') - let output - try { - args.push(cb) - args.push(null) - - output = compile(...args) - } finally { - coreBindings.removeFunction(cb) - } - - if (coreBindings.reset) { - // Explicitly free memory. - // - // NOTE: cwrap() of "compile" will copy the returned pointer into a - // Javascript string and it is not possible to call free() on it. - // reset() however will clear up all allocations. - coreBindings.reset() - } - return output -} - -function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings) { - let boundFunctionStandard: ((input: number, readCallback: Callbacks) => void) | null = null - let boundFunctionSolidity: ((...args: unknown[]) => void) | null = null - - // input (jsontext), callback (ptr) -> output (jsontext) - const compileInternal = bindSolcMethod( - solJson, - 'compileStandard', - 'string', - ['string', 'number'], - null, - ) - - // input (jsontext), callback (ptr), callback_context (ptr) -> output (jsontext) - boundFunctionSolidity = bindSolcMethod( - solJson, - 'solidity_compile', - 'string', - ['string', 'number', 'number'], - null, - ) - - if (!isNil(compileInternal)) { - boundFunctionStandard = function (input: number, readCallback: Callbacks) { - return runWithCallbacks(coreBindings, readCallback, compileInternal!, [input]) - } - } - - if (!isNil(boundFunctionSolidity)) { - boundFunctionStandard = function (input: number, callbacks: Callbacks) { - return runWithCallbacks(coreBindings, callbacks, boundFunctionSolidity as ((...args: unknown[]) => void), [input]) - } - } - - return boundFunctionStandard -} - -function setupCompile( - solJson: SolJson, - core: CoreBindings, -) { - return { - compileJson: bindCompileJson(solJson), - compileStandard: bindCompileStandard(solJson, core), - } -} - -export const setupBindings = (soljson: SolJson) => { - const coreBindings = setupCore(soljson) - const compileBindings = setupCompile(soljson, coreBindings) - - return { coreBindings, compileBindings } -} diff --git a/bindings/compile.ts b/bindings/compile.ts new file mode 100644 index 0000000..b5b9662 --- /dev/null +++ b/bindings/compile.ts @@ -0,0 +1,211 @@ +import assert from 'node:assert' + +import { Callbacks, CoreBindings, ReadCallback, SolJson } from '../deps.ts' +import { isNil } from '../common.ts' +import { bindSolcMethod } from './helpers.ts' + +export function setupCompile(solJson: SolJson, core: CoreBindings) { + return { + compileJson: bindCompileJson(solJson), + compileJsonCallback: bindCompileJsonCallback(solJson, core), + compileJsonMulti: bindCompileJsonMulti(solJson), + compileStandard: bindCompileStandard(solJson, core), + } +} + +/********************** + * COMPILE + **********************/ + +/** + * Returns a binding to the solidity compileJSON method. + * input (text), optimize (bool) -> output (jsontext) + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindCompileJson(solJson: SolJson) { + return bindSolcMethod( + solJson, + 'compileJSON', + 'string', + ['string', 'number'], + null, + ) +} + +/** + * Returns a binding to the solidity compileJSONMulti method. + * input (jsontext), optimize (bool) -> output (jsontext) + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindCompileJsonMulti(solJson: SolJson) { + return bindSolcMethod( + solJson, + 'compileJSONMulti', + 'string', + ['string', 'number'], + null, + ) +} + +/** + * Returns a binding to the solidity compileJSONCallback method. + * input (jsontext), optimize (bool), callback (ptr) -> output (jsontext) + * + * @param solJson The Emscripten compiled Solidity object. + * @param coreBindings The core bound Solidity methods. + */ +function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings) { + const compileInternal = bindSolcMethod<(arg0: string, arg1: number, arg2?: number) => string>( + solJson, + 'compileJSONCallback', + 'string', + ['string', 'number', 'number'], + null, + ) + + if (isNil(compileInternal)) return null + + return function (input: string, optimize: number, readCallback: ReadCallback) { + return runWithCallbacks(solJson, coreBindings, readCallback, compileInternal, [input, optimize]) + } +} + +/** + * Returns a binding to the solidity solidity_compile method with a fallback to + * compileStandard. + * input (jsontext), callback (optional >= v6 only - ptr) -> output (jsontext) + * + * @param solJson The Emscripten compiled Solidity object. + * @param coreBindings The core bound Solidity methods. + */ +function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings) { + let boundFunctionStandard = null + let boundFunctionSolidity: ((jsontext: string, ptr?: number) => string) | null = null + + // input (jsontext), callback (ptr) -> output (jsontext) + const compileInternal = bindSolcMethod<(jsontext: string, ptr?: number) => string>( + solJson, + 'compileStandard', + 'string', + ['string', 'number'], + null, + ) + + // input (jsontext), callback (ptr), callback_context (ptr) -> output (jsontext) + boundFunctionSolidity = bindSolcMethod( + solJson, + 'solidity_compile', + 'string', + ['string', 'number', 'number'], + null, + ) + + if (!isNil(compileInternal)) { + boundFunctionStandard = function (input: string, readCallback: ReadCallback) { + return runWithCallbacks(solJson, coreBindings, readCallback, compileInternal, [input]) + } + } + + if (!isNil(boundFunctionSolidity)) { + boundFunctionStandard = function (input: string, callbacks: Callbacks) { + return runWithCallbacks(solJson, coreBindings, callbacks, boundFunctionSolidity, [input]) + } + } + + return boundFunctionStandard +} + +/********************** + * CALL BACKS + **********************/ + +function wrapCallbackWithKind<Arg extends string>( + coreBindings: CoreBindings, + callback: (...args: Arg[]) => Partial<{ contents: unknown; error: unknown }>, +) { + assert(typeof callback === 'function', 'Invalid callback specified.') + + return function (context: 0, kind: string, data: string, contents: string, error: string) { + // Must be a null pointer. + assert(context === 0, 'Callback context must be null.') + const result = callback(coreBindings.copyFromCString(kind) as Arg, coreBindings.copyFromCString(data) as Arg) + if (typeof result.contents === 'string') { + coreBindings.copyToCString(result.contents, contents) + } + if (typeof result.error === 'string') { + coreBindings.copyToCString(result.error, error) + } + } +} + +// calls compile() with args || cb +function runWithCallbacks<Args extends unknown[]>( + _solJson: SolJson, + coreBindings: CoreBindings, + callbacks: Callbacks | ReadCallback, + compile: (...args: Args) => void, + args: Args, +) { + if (callbacks) { + assert(typeof callbacks === 'object', 'Invalid callback object specified.') + } else { + callbacks = {} + } + + let readCallback = callbacks.import + if (readCallback === undefined) { + readCallback = function () { + return { + error: 'File import callback not supported', + } + } + } + + let singleCallback + // After 0.6.x multiple kind of callbacks are supported. + let smtSolverCallback = callbacks.smtSolver + if (smtSolverCallback === undefined) { + smtSolverCallback = function () { + return { + error: 'SMT solver callback not supported', + } + } + } + + singleCallback = function (kind: 'source' | 'smt-query', data: string) { + if (kind === 'source') { + return readCallback(data) + } else if (kind === 'smt-query') { + return smtSolverCallback(data) + } else { + assert(false, 'Invalid callback kind specified.') + } + } + + singleCallback = wrapCallbackWithKind<'source' | 'smt-query'>(coreBindings, singleCallback) + + const cb = coreBindings.addFunction(singleCallback, 'viiiii') + let output + try { + args.push(cb) + + // Callback context. + args.push(null) + + output = compile(...args) + } finally { + coreBindings.removeFunction(cb) + } + + if (coreBindings.reset) { + // Explicitly free memory. + // + // NOTE: cwrap() of "compile" will copy the returned pointer into a + // Javascript string and it is not possible to call free() on it. + // reset() however will clear up all allocations. + coreBindings.reset() + } + return output +} diff --git a/bindings/core.ts b/bindings/core.ts new file mode 100644 index 0000000..148e0f6 --- /dev/null +++ b/bindings/core.ts @@ -0,0 +1,151 @@ +import { isNil } from '../common.ts' +import { CoreBindings, License, SolJson } from '../deps.ts' +import { bindSolcMethod, bindSolcMethodWithFallbackFunc } from './helpers.ts' + +export function setupCore(solJson: SolJson): CoreBindings { + const core = { + alloc: bindAlloc<(n: number) => number>(solJson), + license: bindLicense(solJson), + version: bindVersion<() => string>(solJson), + reset: bindReset(solJson), + } + + const helpers = { + addFunction: unboundAddFunction.bind(this, solJson), + removeFunction: unboundRemoveFunction.bind(this, solJson), + + copyFromCString: unboundCopyFromCString.bind(this, solJson), + copyToCString: unboundCopyToCString.bind(this, solJson, core.alloc), + } + + return { + ...core, + ...helpers, + } +} + +/********************** + * Core Functions + **********************/ + +/** + * Returns a binding to the solidity_alloc function. + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindAlloc<T>(solJson: SolJson) { + const allocBinding = bindSolcMethod<T>( + solJson, + 'solidity_alloc', + 'number', + ['number'], + null, + ) + + // the fallback malloc is not a cwrap function and should just be returned + // directly in-case the alloc binding could not happen. + if (isNil(allocBinding)) { + return solJson._malloc + } + + return allocBinding +} + +/** + * Returns a binding to the solidity_version method. + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindVersion<T>(solJson: SolJson) { + return bindSolcMethodWithFallbackFunc<T>( + solJson, + 'solidity_version', + 'string', + [], + 'version', + ) +} + +/** + * Returns a binding to the solidity_license method. + * + * If the current solJson version < 0.4.14 then this will bind an empty function. + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindLicense(solJson: SolJson) { + return bindSolcMethodWithFallbackFunc<() => License>( + solJson, + 'solidity_license', + 'string', + [], + 'license', + () => { + }, + ) +} + +/** + * Returns a binding to the solidity_reset method. + * + * @param solJson The Emscripten compiled Solidity object. + */ +function bindReset(solJson: SolJson) { + return bindSolcMethod( + solJson, + 'solidity_reset', + null, + [], + null, + ) +} + +/********************** + * Helpers Functions + **********************/ + +/** + * Copy to a C string. + * + * Allocates memory using solc's allocator. + * + * Before 0.6.0: + * Assuming copyToCString is only used in the context of wrapCallback, solc will free these pointers. + * See https://github.com/ethereum/solidity/blob/v0.5.13/libsolc/libsolc.h#L37-L40 + * + * After 0.6.0: + * The duty is on solc-js to free these pointers. We accomplish that by calling `reset` at the end. + * + * @param solJson The Emscripten compiled Solidity object. + * @param alloc The memory allocation function. + * @param str The source string being copied to a C string. + * @param ptr The pointer location where the C string will be set. + */ +function unboundCopyToCString(solJson: SolJson, alloc: (n: number) => number, str: string, ptr: number) { + const length = solJson.lengthBytesUTF8(str) + + const buffer = alloc(length + 1) + + solJson.stringToUTF8(str, buffer, length + 1) + solJson.setValue(ptr, buffer, '*') +} + +/** + * Wrapper over Emscripten's C String copying function (which can be different + * on different versions). + * + * @param solJson The Emscripten compiled Solidity object. + * @param ptr The pointer location where the C string will be referenced. + */ +function unboundCopyFromCString(solJson: SolJson, ptr: number) { + const copyFromCString = solJson.UTF8ToString || solJson.Pointer_stringify + return copyFromCString(ptr) +} + +function unboundAddFunction(solJson: SolJson, func: (...args: unknown[]) => unknown, signature?: string) { + return (solJson.addFunction || solJson.Runtime.addFunction)(func, signature) +} + +function unboundRemoveFunction(solJson: SolJson, ptr: number) { + return (solJson.removeFunction || solJson.Runtime.removeFunction)(ptr) +} diff --git a/bindings/helpers.ts b/bindings/helpers.ts new file mode 100644 index 0000000..fff9845 --- /dev/null +++ b/bindings/helpers.ts @@ -0,0 +1,50 @@ +import { isNil } from '../common.ts' +import { SolJson } from '../deps.ts' + +export function bindSolcMethod<T>( + solJson: SolJson, + method: string, + returnType: string | null, + args: string[], + defaultValue?: unknown, +): T { + if (isNil((solJson as any)[`_${method}`]) && defaultValue !== undefined) { + return defaultValue as T + } + + return solJson.cwrap<T>(method, returnType, args) +} + +export function bindSolcMethodWithFallbackFunc<T>( + solJson: SolJson, + method: string, + returnType: string | null, + args: string[], + fallbackMethod: string, + finalFallback: (() => void) | undefined = undefined, +): T { + const methodFunc = bindSolcMethod<T>(solJson, method, returnType, args, null) + + if (!isNil(methodFunc)) { + return methodFunc as T + } + + return bindSolcMethod<T>(solJson, fallbackMethod, returnType, args, finalFallback) +} + +export function getSupportedMethods(solJson: SolJson) { + return { + licenseSupported: anyMethodExists(solJson, 'solidity_license'), + versionSupported: anyMethodExists(solJson, 'solidity_version'), + allocSupported: anyMethodExists(solJson, 'solidity_alloc'), + resetSupported: anyMethodExists(solJson, 'solidity_reset'), + compileJsonSupported: anyMethodExists(solJson, 'compileJSON'), + compileJsonMultiSupported: anyMethodExists(solJson, 'compileJSONMulti'), + compileJsonCallbackSuppported: anyMethodExists(solJson, 'compileJSONCallback'), + compileJsonStandardSupported: anyMethodExists(solJson, 'compileStandard', 'solidity_compile'), + } +} + +function anyMethodExists(solJson: SolJson, ...names: string[]) { + return names.some((name) => !isNil((solJson as any)[`_${name}`])) +} diff --git a/bindings/index.ts b/bindings/index.ts new file mode 100644 index 0000000..58350b2 --- /dev/null +++ b/bindings/index.ts @@ -0,0 +1,20 @@ +import { SolJson } from '../deps.ts' +import { setupCompile } from './compile.ts' +import { setupCore } from './core.ts' +import { getSupportedMethods } from './helpers.ts' + +export default function setupBindings(solJson: SolJson) { + const coreBindings = setupCore(solJson) + + const compileBindings = setupCompile(solJson, coreBindings) + + const methodFlags = getSupportedMethods(solJson) + + return { + methodFlags, + + coreBindings, + + compileBindings, + } +} diff --git a/deno.json b/deno.json index affe199..ad5427d 100644 --- a/deno.json +++ b/deno.json @@ -3,6 +3,9 @@ "files": { "include": ["./**/*.ts"], "exclude": ["./**/*.js"] + }, + "rules": { + "exclude": ["no-explicit-any"] } }, "fmt": { @@ -15,6 +18,8 @@ "lineWidth": 120 }, "imports": { + "@noble/hashes": "npm:@noble/hashes@^1.7.1", + "@std/semver": "jsr:@std/semver@^1.0.4", "solc": "./mod.ts", "solc/download": "./download.ts", "solc/types": "./types.ts", diff --git a/deno.lock b/deno.lock index f12661d..07832b7 100644 --- a/deno.lock +++ b/deno.lock @@ -1,5 +1,13 @@ { - "version": "3", + "version": "4", + "specifiers": { + "jsr:@std/semver@^1.0.4": "1.0.4" + }, + "jsr": { + "@std/semver@1.0.4": { + "integrity": "a62af791917d8fd6c48d6ebbb872f83fad3fc6671ffadbbd39ea229c2d34d175" + } + }, "remote": { "https://deno.land/std@0.221.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975", "https://deno.land/std@0.221.0/assert/_diff.ts": "4bf42969aa8b1a33aaf23eb8e478b011bfaa31b82d85d2ff4b5c4662d8780d2b", @@ -46,5 +54,11 @@ "https://deno.land/std@0.221.0/testing/_test_suite.ts": "f10a8a6338b60c403f07a76f3f46bdc9f1e1a820c0a1decddeb2949f7a8a0546", "https://deno.land/std@0.221.0/testing/bdd.ts": "7a8ac58eded80e6fefa7cf7538927e88781cf5f247c04b35261c3213316e2dd0", "https://raw.githubusercontent.com/ethereum/solc-js/540a9643cd7974e329287ebf8d4c2c70d744c11d/common/types.ts": "8ab10911ffceee409aab33f37237dcb1d3207c8ad310c291e2abcb9c7a5f4d2c" + }, + "workspace": { + "dependencies": [ + "jsr:@std/semver@^1.0.4", + "npm:@noble/hashes@^1.7.1" + ] } } diff --git a/download.ts b/download.ts index 1d2dc19..5cfe02d 100644 --- a/download.ts +++ b/download.ts @@ -5,10 +5,10 @@ import { copy, readerFromStreamReader } from './deps.ts' * @param path download destination * @param version compiler version. if not specified, latest is downloaded */ -export const download = async (path = './soljson.js', version?: string) => { +export const download = async (path = './soljson.cjs', version?: string) => { console.log(`Fetching releases...`) const { releases, latestRelease } = - (await fetch('https://solc-bin.ethereum.org/bin/list.json').then((res) => res.json())) as { + (await fetch('https://binaries.soliditylang.org/emscripten-wasm32/list.json').then((res) => res.json())) as { releases: Record<string, string> latestRelease: string } @@ -17,9 +17,9 @@ export const download = async (path = './soljson.js', version?: string) => { if (!jsFile) throw new Error(`version ${version} not found`) - console.log(`Downloading soljson from https://solc-bin.ethereum.org/bin/${jsFile}...`) + console.log(`Downloading soljson from https://binaries.soliditylang.org/emscripten-wasm32/${jsFile}...`) - const res = await fetch(`https://solc-bin.ethereum.org/bin/${jsFile}`) + const res = await fetch(`https://binaries.soliditylang.org/emscripten-wasm32/${jsFile}`) const rdr = res.body?.getReader() diff --git a/download_test.ts b/download_test.ts index 5fd8870..e978a2c 100644 --- a/download_test.ts +++ b/download_test.ts @@ -4,23 +4,23 @@ import { download } from 'solc/download' import { exists } from './helpers_test.ts' describe('solc/download.ts', () => { - it('downloads latest version to soljson.js file', async () => { + it('downloads latest version to soljson.cjs file', async () => { await download() - expect(await exists('./soljson.js')).toBe(true) + expect(await exists('./soljson.cjs')).toBe(true) }) it('downloads latest version to any file path', async () => { - await download('./solc.js') - expect(await exists('./solc.js')).toBe(true) - await Deno.remove('./solc.js') + await download('./solc.cjs') + expect(await exists('./solc.cjs')).toBe(true) + await Deno.remove('./solc.cjs') }) it('downloads a specific version', async () => { - const jsFile = await download('./soljson.js', '0.8.17') + const jsFile = await download('./soljson.cjs', '0.8.17') - expect(jsFile).toEqual('soljson-v0.8.17+commit.8df45f5f.js') + expect(jsFile).toEqual('solc-emscripten-wasm32-v0.8.17+commit.8df45f5f.js') }) it('throws if version does not exist', async () => { try { - await download('./soljson.js', '12.456.789') + await download('./soljson.cjs', '12.456.789') } catch (e) { expect((e as Error).message).toEqual('version 12.456.789 not found') } diff --git a/examples/erc20/mod.ts b/examples/erc20/mod.ts index 18f3b6d..0a7cb17 100644 --- a/examples/erc20/mod.ts +++ b/examples/erc20/mod.ts @@ -1,13 +1,13 @@ import { wrapper } from 'solc' import { Input } from 'solc/types' import { download } from 'solc/download' -import { createRequire } from '../../helpers_test.ts' import { exists } from '../../helpers_test.ts' -if (!(await exists('./soljson.js'))) await download() +if (!(await exists('./soljson.cjs'))) await download() -const require = createRequire(import.meta.url) -const solc = wrapper(require('./soljson.js')) +const mod = await import('./soljson.cjs') + +const solc = wrapper(mod.default) const MyToken = await Deno.readTextFile('./MyToken.sol') const ERC20 = await Deno.readTextFile('./ERC20.sol') diff --git a/examples/with-library/mod.ts b/examples/with-library/mod.ts index a2c532a..93b0a09 100644 --- a/examples/with-library/mod.ts +++ b/examples/with-library/mod.ts @@ -4,10 +4,10 @@ import { download } from 'solc/download' import { createRequire } from '../../helpers_test.ts' import { exists } from '../../helpers_test.ts' -if (!(await exists('./soljson.js'))) await download() +if (!(await exists('./soljson.cjs'))) await download() const require = createRequire(import.meta.url) -const solc = wrapper(require('./soljson.js')) +const solc = wrapper(require('./soljson.cjs')) const Example = await Deno.readTextFile('./Example.sol') const LibString = await Deno.readTextFile('./LibString.sol') diff --git a/mod.ts b/mod.ts index 4b1d095..ee7eb29 100644 --- a/mod.ts +++ b/mod.ts @@ -1,4 +1,4 @@ -import { setupBindings } from './bindings.ts' +import setupBindings from './bindings/index.ts' import { CompileBindings, SolJson } from './deps.ts' import type { Wrapper } from './types.ts' @@ -6,6 +6,10 @@ function compileStandardWrapper(compile: CompileBindings, inputRaw: string, read return compile.compileStandard(inputRaw, readCallback as number) } +if (!globalThis.__dirname) { + globalThis.__dirname = import.meta.url +} + /** * Wrap Solidity compiler into a JS interface * @param soljson WebAssembly compiler module diff --git a/mod_test.ts b/mod_test.ts index f1283dd..a86fbad 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -7,6 +7,8 @@ import type { Input, Output, Wrapper } from 'solc/types' const require = createRequire(import.meta.url) +globalThis.__dirname = import.meta.dirname! + const contract = ` // SPDX-License-Identifier: MIT pragma solidity >=0.8; @@ -19,8 +21,8 @@ contract HelloWorld { describe('solc/wrapper.ts', () => { let solc: Wrapper beforeAll(async () => { - await download('./soljson_test.js', '0.8.18') - solc = wrapper(require('./soljson_test.js')) + await download('./soljson_test.cjs', '0.8.18') + solc = wrapper(require('./soljson_test.cjs')) }) it('returns JS interface', () => { expect(solc.compile).toBeDefined() diff --git a/types.ts b/types.ts index 4f1de87..e04eca7 100644 --- a/types.ts +++ b/types.ts @@ -129,7 +129,7 @@ export type DocMethods = Record< } > export type GasEstimates = Partial<{ - creation: { codeDepositCost: string; executionCost: string; totalCost: string } + creation: { codeDepositCost: string; executionCost: string; totalCost: string } | string[] internal: Record<string, string> external: Record<string, string> }> @@ -187,9 +187,10 @@ export type CompiledContract = { } export type Output = { + interface: string error?: CompilationError errors: CompilationError[] - contracts: Record<string, Record<string, CompiledContract>> + contracts: { gasEstimates?: GasEstimates } & Record<string, Record<string, CompiledContract>> sourceList?: string[] sources?: Record<string, { id: number; AST?: any }> } From 06c50bbac1578d28ddc20ed98fbb4f9d3211ab7d Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Wed, 26 Feb 2025 23:39:49 +0200 Subject: [PATCH 02/16] move to jsr --- deno.json | 8 ++--- deno.lock | 93 +++++++++++++++++++++--------------------------- deps.ts | 4 +-- download_test.ts | 4 +-- mod_test.ts | 4 +-- 5 files changed, 51 insertions(+), 62 deletions(-) diff --git a/deno.json b/deno.json index ad5427d..59bb88c 100644 --- a/deno.json +++ b/deno.json @@ -18,12 +18,12 @@ "lineWidth": 120 }, "imports": { - "@noble/hashes": "npm:@noble/hashes@^1.7.1", - "@std/semver": "jsr:@std/semver@^1.0.4", + "@std/expect": "jsr:@std/expect@^1.0.13", + "@std/io": "jsr:@std/io@^0.225.2", + "@std/testing": "jsr:@std/testing@^1.0.9", "solc": "./mod.ts", "solc/download": "./download.ts", - "solc/types": "./types.ts", - "solc/url_resolver": "./url_resolver.ts" + "solc/types": "./types.ts" }, "test": { "exclude": ["./**/*.js", "examples"] diff --git a/deno.lock b/deno.lock index 07832b7..20d6003 100644 --- a/deno.lock +++ b/deno.lock @@ -1,64 +1,53 @@ { "version": "4", "specifiers": { - "jsr:@std/semver@^1.0.4": "1.0.4" + "jsr:@std/assert@^1.0.10": "1.0.11", + "jsr:@std/assert@^1.0.11": "1.0.11", + "jsr:@std/bytes@^1.0.5": "1.0.5", + "jsr:@std/expect@^1.0.13": "1.0.13", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/io@~0.225.2": "0.225.2", + "jsr:@std/testing@^1.0.9": "1.0.9" }, "jsr": { - "@std/semver@1.0.4": { - "integrity": "a62af791917d8fd6c48d6ebbb872f83fad3fc6671ffadbbd39ea229c2d34d175" + "@std/assert@1.0.11": { + "integrity": "2461ef3c368fe88bc60e186e7744a93112f16fd110022e113a0849e94d1c83c1", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/bytes@1.0.5": { + "integrity": "4465dd739d7963d964c809202ebea6d5c6b8e3829ef25c6a224290fbb8a1021e" + }, + "@std/expect@1.0.13": { + "integrity": "d8e236c7089cd9fcf5e6032f27dadc3db6349d0aee48c15bc71d717bca5baa42", + "dependencies": [ + "jsr:@std/assert@^1.0.11", + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/io@0.225.2": { + "integrity": "3c740cd4ee4c082e6cfc86458f47e2ab7cb353dc6234d5e9b1f91a2de5f4d6c7", + "dependencies": [ + "jsr:@std/bytes" + ] + }, + "@std/testing@1.0.9": { + "integrity": "9bdd4ac07cb13e7594ac30e90f6ceef7254ac83a9aeaa089be0008f33aab5cd4", + "dependencies": [ + "jsr:@std/assert@^1.0.10", + "jsr:@std/internal" + ] } }, - "remote": { - "https://deno.land/std@0.221.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975", - "https://deno.land/std@0.221.0/assert/_diff.ts": "4bf42969aa8b1a33aaf23eb8e478b011bfaa31b82d85d2ff4b5c4662d8780d2b", - "https://deno.land/std@0.221.0/assert/_format.ts": "0ba808961bf678437fb486b56405b6fefad2cf87b5809667c781ddee8c32aff4", - "https://deno.land/std@0.221.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", - "https://deno.land/std@0.221.0/assert/assert_equals.ts": "4497c56fe7d2993b0d447926702802fc0becb44e319079e8eca39b482ee01b4e", - "https://deno.land/std@0.221.0/assert/assert_false.ts": "6f382568e5128c0f855e5f7dbda8624c1ed9af4fcc33ef4a9afeeedcdce99769", - "https://deno.land/std@0.221.0/assert/assert_instance_of.ts": "72dc1faff1e248692d873c89382fa1579dd7b53b56d52f37f9874a75b11ba444", - "https://deno.land/std@0.221.0/assert/assert_is_error.ts": "6596f2b5ba89ba2fe9b074f75e9318cda97a2381e59d476812e30077fbdb6ed2", - "https://deno.land/std@0.221.0/assert/assert_match.ts": "ec2d9680ed3e7b9746ec57ec923a17eef6d476202f339ad91d22277d7f1d16e1", - "https://deno.land/std@0.221.0/assert/assert_not_instance_of.ts": "8f720d92d83775c40b2542a8d76c60c2d4aeddaf8713c8d11df8984af2604931", - "https://deno.land/std@0.221.0/assert/assert_not_match.ts": "b4b7c77f146963e2b673c1ce4846473703409eb93f5ab0eb60f6e6f8aeffe39f", - "https://deno.land/std@0.221.0/assert/assert_not_strict_equals.ts": "da0b8ab60a45d5a9371088378e5313f624799470c3b54c76e8b8abeec40a77be", - "https://deno.land/std@0.221.0/assert/assert_object_match.ts": "e85e5eef62a56ce364c3afdd27978ccab979288a3e772e6855c270a7b118fa49", - "https://deno.land/std@0.221.0/assert/assert_strict_equals.ts": "0425a98f70badccb151644c902384c12771a93e65f8ff610244b8147b03a2366", - "https://deno.land/std@0.221.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", - "https://deno.land/std@0.221.0/assert/equal.ts": "fae5e8a52a11d3ac694bbe1a53e13a7969e3f60791262312e91a3e741ae519e2", - "https://deno.land/std@0.221.0/bytes/copy.ts": "f29c03168853720dfe82eaa57793d0b9e3543ebfe5306684182f0f1e3bfd422a", - "https://deno.land/std@0.221.0/expect/_assert_equals.ts": "08a5ba74c1c7ca51c4c2c33158509746c560777ad3cb8996a55d85a8d57c351c", - "https://deno.land/std@0.221.0/expect/_assert_not_equals.ts": "f8c56aafbc12b2d49bb5e1478f02a3ae8a6fd884eff18ccbc899a94829eb1510", - "https://deno.land/std@0.221.0/expect/_asymmetric_matchers.ts": "bf2385fc9a943f0600f7870c8dfcbfd0ab5d633fe3c45b84339016e0d8069ac4", - "https://deno.land/std@0.221.0/expect/_build_message.ts": "bef41b72d68c5f11c4bea867c118f7c4ca94ed0d1c00e601ed58ee08c857b534", - "https://deno.land/std@0.221.0/expect/_constants.ts": "751a014c4b803ad21287529d55d213d8b5eb34d203cca9509e4c9b84ced440a8", - "https://deno.land/std@0.221.0/expect/_custom_equality_tester.ts": "9426916863d2b740ae3ec74e2de5f2ec79d36bb1a62bdd5965a9b9543c8ee46d", - "https://deno.land/std@0.221.0/expect/_diff.ts": "4bf42969aa8b1a33aaf23eb8e478b011bfaa31b82d85d2ff4b5c4662d8780d2b", - "https://deno.land/std@0.221.0/expect/_equal.ts": "f2d4f3a10f91cd6c21deefc8facdbc9e6f07a828e68b8e50049a33f8a4c3c6d4", - "https://deno.land/std@0.221.0/expect/_extend.ts": "ac8ab93dbe66bb2d0d356409e84e9b884babbc404c8a8d63be73509055ed16be", - "https://deno.land/std@0.221.0/expect/_format.ts": "e456ee08d8255b34b8ff126be2d40adf3bbf695a7e2d82d0a9cd7bb223e40ddb", - "https://deno.land/std@0.221.0/expect/_inspect_args.ts": "6cc9b3809e6f9671b35d0305d1ed7cc340b00b0455731b0b47b6c2ae707f8f27", - "https://deno.land/std@0.221.0/expect/_matchers.ts": "a14db5f034dbf6f783481c4f2675e8adbeedcf6dbc7f8e914cf2a32a4fd84686", - "https://deno.land/std@0.221.0/expect/_mock_util.ts": "7e79e07eb869ff71b96601ac76807c745465bd3c5a3df622abf44c28a0c4ca8c", - "https://deno.land/std@0.221.0/expect/_types.ts": "2ca1780e46377cc10c886b96a9f796df5a82f08e545273729fdc2083a916357f", - "https://deno.land/std@0.221.0/expect/_utils.ts": "fc45069227d1c5a04f642b9224f060017eb02923159a4848d79a7a3fcef53c55", - "https://deno.land/std@0.221.0/expect/expect.ts": "cd4312c30a9291c25f737628edcee67493454ec35ddccd20b46ba89c0df0d6c3", - "https://deno.land/std@0.221.0/expect/fn.ts": "3b11d35a8d276c553a3a40df5da6ac21f207aa671a2143370b2f728449b1df22", - "https://deno.land/std@0.221.0/expect/mod.ts": "dc79508c6f554d70ef087fdb726d09add7a48f5e612aabc2d951e5cc69c4529a", - "https://deno.land/std@0.221.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a", - "https://deno.land/std@0.221.0/io/_constants.ts": "3c7ad4695832e6e4a32e35f218c70376b62bc78621ef069a4a0a3d55739f8856", - "https://deno.land/std@0.221.0/io/buffer.ts": "4d1f805f350433e418002accec798bc6c33ce18f614afa65f987c202d7b2234e", - "https://deno.land/std@0.221.0/io/copy.ts": "63c6a4acf71fb1e89f5e47a7b3b2972f9d2c56dd645560975ead72db7eb23f61", - "https://deno.land/std@0.221.0/io/reader_from_stream_reader.ts": "a75bbc93f39df8b0e372cc1fbdc416a7cbf2a39fc4c09ddb057f1241100191c5", - "https://deno.land/std@0.221.0/io/types.ts": "acecb3074c730b5ff487ba4fe9ce51e67bd982aa07c95e5f5679b7b2f24ad129", - "https://deno.land/std@0.221.0/io/write_all.ts": "24aac2312bb21096ae3ae0b102b22c26164d3249dff96dbac130958aa736f038", - "https://deno.land/std@0.221.0/testing/_test_suite.ts": "f10a8a6338b60c403f07a76f3f46bdc9f1e1a820c0a1decddeb2949f7a8a0546", - "https://deno.land/std@0.221.0/testing/bdd.ts": "7a8ac58eded80e6fefa7cf7538927e88781cf5f247c04b35261c3213316e2dd0", - "https://raw.githubusercontent.com/ethereum/solc-js/540a9643cd7974e329287ebf8d4c2c70d744c11d/common/types.ts": "8ab10911ffceee409aab33f37237dcb1d3207c8ad310c291e2abcb9c7a5f4d2c" - }, "workspace": { "dependencies": [ - "jsr:@std/semver@^1.0.4", - "npm:@noble/hashes@^1.7.1" + "jsr:@std/expect@^1.0.13", + "jsr:@std/io@~0.225.2", + "jsr:@std/testing@^1.0.9" ] } } diff --git a/deps.ts b/deps.ts index 83b62fc..8877c92 100644 --- a/deps.ts +++ b/deps.ts @@ -1,5 +1,5 @@ -export { readerFromStreamReader } from 'https://deno.land/std@0.221.0/io/reader_from_stream_reader.ts' -export { copy } from 'https://deno.land/std@0.221.0/io/copy.ts' +export { readerFromStreamReader } from '@std/io/reader-from-stream-reader' +export { copy } from '@std/io/copy' export type { Alloc, Callbacks, diff --git a/download_test.ts b/download_test.ts index e978a2c..af1d443 100644 --- a/download_test.ts +++ b/download_test.ts @@ -1,5 +1,5 @@ -import { describe, it } from 'https://deno.land/std@0.221.0/testing/bdd.ts' -import { expect } from 'https://deno.land/std@0.221.0/expect/mod.ts' +import { describe, it } from '@std/testing/bdd' +import { expect } from '@std/expect' import { download } from 'solc/download' import { exists } from './helpers_test.ts' diff --git a/mod_test.ts b/mod_test.ts index a86fbad..73364ea 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -1,5 +1,5 @@ -import { beforeAll, describe, it } from 'https://deno.land/std@0.221.0/testing/bdd.ts' -import { expect } from 'https://deno.land/std@0.221.0/expect/mod.ts' +import { beforeAll, describe, it } from '@std/testing/bdd' +import { expect } from '@std/expect' import { wrapper } from 'solc' import { createRequire } from './helpers_test.ts' import { download } from 'solc/download' From 59604c16ecea26c5a515f5e72275bdfcf9283106 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 00:03:43 +0200 Subject: [PATCH 03/16] rewrite types and remove legacy compat code --- bindings/compile.ts | 23 +- bindings/core.ts | 14 +- bindings/helpers.ts | 2 +- deps.ts | 13 -- types.ts | 531 ++++++++++++++++++++++++++++---------------- 5 files changed, 354 insertions(+), 229 deletions(-) diff --git a/bindings/compile.ts b/bindings/compile.ts index b5b9662..fea2250 100644 --- a/bindings/compile.ts +++ b/bindings/compile.ts @@ -1,8 +1,8 @@ import assert from 'node:assert' -import { Callbacks, CoreBindings, ReadCallback, SolJson } from '../deps.ts' import { isNil } from '../common.ts' import { bindSolcMethod } from './helpers.ts' +import { Callbacks, CoreBindings, ReadCallback, SolJson } from 'solc/types' export function setupCompile(solJson: SolJson, core: CoreBindings) { return { @@ -73,8 +73,7 @@ function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings) { } /** - * Returns a binding to the solidity solidity_compile method with a fallback to - * compileStandard. + * Returns a binding to the solidity solidity_compile method. * input (jsontext), callback (optional >= v6 only - ptr) -> output (jsontext) * * @param solJson The Emscripten compiled Solidity object. @@ -84,15 +83,6 @@ function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings) { let boundFunctionStandard = null let boundFunctionSolidity: ((jsontext: string, ptr?: number) => string) | null = null - // input (jsontext), callback (ptr) -> output (jsontext) - const compileInternal = bindSolcMethod<(jsontext: string, ptr?: number) => string>( - solJson, - 'compileStandard', - 'string', - ['string', 'number'], - null, - ) - // input (jsontext), callback (ptr), callback_context (ptr) -> output (jsontext) boundFunctionSolidity = bindSolcMethod( solJson, @@ -102,12 +92,6 @@ function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings) { null, ) - if (!isNil(compileInternal)) { - boundFunctionStandard = function (input: string, readCallback: ReadCallback) { - return runWithCallbacks(solJson, coreBindings, readCallback, compileInternal, [input]) - } - } - if (!isNil(boundFunctionSolidity)) { boundFunctionStandard = function (input: string, callbacks: Callbacks) { return runWithCallbacks(solJson, coreBindings, callbacks, boundFunctionSolidity, [input]) @@ -130,7 +114,8 @@ function wrapCallbackWithKind<Arg extends string>( return function (context: 0, kind: string, data: string, contents: string, error: string) { // Must be a null pointer. assert(context === 0, 'Callback context must be null.') - const result = callback(coreBindings.copyFromCString(kind) as Arg, coreBindings.copyFromCString(data) as Arg) + console.log({ kind, data }) + const result = callback(coreBindings.copyFromCString(kind), coreBindings.copyFromCString(data)) if (typeof result.contents === 'string') { coreBindings.copyToCString(result.contents, contents) } diff --git a/bindings/core.ts b/bindings/core.ts index 148e0f6..e80cfdb 100644 --- a/bindings/core.ts +++ b/bindings/core.ts @@ -1,5 +1,5 @@ import { isNil } from '../common.ts' -import { CoreBindings, License, SolJson } from '../deps.ts' +import { type CoreBindings, type License, Reset, type SolJson } from 'solc/types' import { bindSolcMethod, bindSolcMethodWithFallbackFunc } from './helpers.ts' export function setupCore(solJson: SolJson): CoreBindings { @@ -11,10 +11,13 @@ export function setupCore(solJson: SolJson): CoreBindings { } const helpers = { + // @ts-expect-error binding to this addFunction: unboundAddFunction.bind(this, solJson), + // @ts-expect-error binding to this removeFunction: unboundRemoveFunction.bind(this, solJson), - + // @ts-expect-error binding to this copyFromCString: unboundCopyFromCString.bind(this, solJson), + // @ts-expect-error binding to this copyToCString: unboundCopyToCString.bind(this, solJson, core.alloc), } @@ -74,7 +77,7 @@ function bindVersion<T>(solJson: SolJson) { * @param solJson The Emscripten compiled Solidity object. */ function bindLicense(solJson: SolJson) { - return bindSolcMethodWithFallbackFunc<() => License>( + return bindSolcMethodWithFallbackFunc<License>( solJson, 'solidity_license', 'string', @@ -91,7 +94,7 @@ function bindLicense(solJson: SolJson) { * @param solJson The Emscripten compiled Solidity object. */ function bindReset(solJson: SolJson) { - return bindSolcMethod( + return bindSolcMethod<Reset>( solJson, 'solidity_reset', null, @@ -138,8 +141,7 @@ function unboundCopyToCString(solJson: SolJson, alloc: (n: number) => number, st * @param ptr The pointer location where the C string will be referenced. */ function unboundCopyFromCString(solJson: SolJson, ptr: number) { - const copyFromCString = solJson.UTF8ToString || solJson.Pointer_stringify - return copyFromCString(ptr) + return solJson.UTF8ToString(ptr) } function unboundAddFunction(solJson: SolJson, func: (...args: unknown[]) => unknown, signature?: string) { diff --git a/bindings/helpers.ts b/bindings/helpers.ts index fff9845..5248555 100644 --- a/bindings/helpers.ts +++ b/bindings/helpers.ts @@ -1,5 +1,5 @@ import { isNil } from '../common.ts' -import { SolJson } from '../deps.ts' +import { SolJson } from 'solc/types' export function bindSolcMethod<T>( solJson: SolJson, diff --git a/deps.ts b/deps.ts index 8877c92..51d8a5c 100644 --- a/deps.ts +++ b/deps.ts @@ -1,15 +1,2 @@ export { readerFromStreamReader } from '@std/io/reader-from-stream-reader' export { copy } from '@std/io/copy' -export type { - Alloc, - Callbacks, - CompileBindings, - CoreBindings, - LibraryAddresses, - License, - ReadCallback, - Reset, - SolJson, - Version, - Wrapper, -} from 'https://raw.githubusercontent.com/ethereum/solc-js/540a9643cd7974e329287ebf8d4c2c70d744c11d/common/types.ts' diff --git a/types.ts b/types.ts index e04eca7..110d52b 100644 --- a/types.ts +++ b/types.ts @@ -1,210 +1,361 @@ -import type { CoreBindings as Bindings, LibraryAddresses, Wrapper as SolcWrapper } from './deps.ts' - -// Taken from https://stackoverflow.com/a/68404823/11889402 -type DotPrefix<T extends string> = T extends '' ? '' : `.${T}` - -type DotNestedKeys<T> = - (T extends object - ? { [K in Exclude<keyof T, symbol>]: `${K}${DotPrefix<DotNestedKeys<T[K]>>}` }[Exclude<keyof T, symbol>] - : '') extends infer D ? Extract<D, string> : never - -type OutputSelection = DotNestedKeys<Omit<CompiledContract, 'abi'>> | 'abi' | '*' | 'ast' - -export type InputSettings = Partial<{ - remappings: string[] - optimizer: Partial<{ - enabled: boolean - runs: number - details: { - peephole: boolean - jumpdestRemover: boolean - deduplicate: boolean - orderLiterals: boolean - cse: boolean - constantOptimizer: boolean - yul: boolean - yulDetails: { - /** - * Improve allocation of stack slots for variables, can free up stack slots early. ctivated by default if the Yul optimizer is activated. - */ - stackAllocation: boolean - /** - * Select optimization steps to be applied. - * Optional, the optimizer will use the default sequence if omitted. - */ - optimizerSteps: string - } - } - }> - outputSelection: Record<string, Record<string, OutputSelection[]>> - libraries: LibraryAddresses -}> - -export type Input = { - /** - * Source code language. Currently supported are "Solidity" and "Yul" - */ - language: 'Solidity' | 'Yul' - sources: Record< - string, - { content: string; keccak256?: `0x${string}` } | { urls: string[]; keccak256?: `0x${string}` } - > - settings?: InputSettings +/** + * A mapping between libraries and the addresses to which they were deployed. + * + * Containing support for two level configuration, These two level + * configurations can be seen below. + * + * { + * "lib.sol:L1": "0x...", + * "lib.sol:L2": "0x...", + * "lib.sol": {"L3": "0x..."} + * } + */ +export interface LibraryAddresses { + [qualifiedNameOrSourceUnit: string]: string | { [unqualifiedLibraryName: string]: string } } -export type LegacyAssemblyCode = { - begin: number - end: number - name: string - source: number - value?: string +/** + * A mapping between libraries and lists of placeholder instances present in their hex-encoded bytecode. + * For each placeholder its length and the position of the first character is stored. + * + * Each start and length entry will always directly refer to the position in + * binary and not hex-encoded bytecode. + */ +export interface LinkReferences { + [libraryLabel: string]: Array<{ start: number; length: number }> } -export type Assembly = string | null | undefined | { - '.code': LegacyAssemblyCode[] - '.data': { - '.auxdata': string - '.code': LegacyAssemblyCode[] +export interface SolJson { + /** + * Returns a native JavaScript wrapper for a C function. + * + * This is similar to ccall(), but returns a JavaScript function that can be + * reused as many times as needed. The C function can be defined in a C file, + * or be a C-compatible C++ function defined using extern "C" (to prevent + * name mangling). + * + * @param ident The name of the C function to be called. + * + * @param returnType The return type of the function. This can be "number", + * "string" or "array", which correspond to the appropriate JavaScript + * types (use "number" for any C pointer, and "array" for JavaScript arrays + * and typed arrays; note that arrays are 8-bit), or for a void function it + * can be null (note: the JavaScript null value, * not a string containing + * the word “null”). + * + * @param argTypes An array of the types of arguments for the function (if + * there are no arguments, this can be omitted). Types are as in returnType, + * except that array is not supported as there is no way for us to know the + * length of the array). + * + * @returns A JavaScript function that can be used for running the C function. + */ + cwrap<T>(ident: string, returnType: string | null, argTypes: string[]): T + + /** + * Sets a value at a specific memory address at run-time. + * + * Note: + * setValue() and getValue() only do aligned writes and reads. + * + * The type is an LLVM IR type (one of i8, i16, i32, i64, float, double, or + * a pointer type like i8* or just *), not JavaScript types as used in ccall() + * or cwrap(). This is a lower-level operation, and we do need to care what + * specific type is being used. + * + * @param ptr A pointer (number) representing the memory address. + * + * @param value The value to be stored + * + * @param type An LLVM IR type as a string (see “note” above). + * + * @param noSafe Developers should ignore this variable. It is only + * used in SAFE_HEAP compilation mode, where it can help avoid infinite recursion + * in some specialist use cases. + */ + setValue(ptr: number, value: any, type: string, noSafe?: boolean): void + + /** + * Given a pointer ptr to a null-terminated UTF8-encoded string in the + * Emscripten HEAP, returns a copy of that string as a JavaScript String + * object. + * + * @param ptr A pointer to a null-terminated UTF8-encoded string in the + * Emscripten HEAP. + * + * @param maxBytesToRead An optional length that specifies the maximum number + * of bytes to read. You can omit this parameter to scan the string until the + * first 0 byte. If maxBytesToRead is passed, and the string at + * [ptr, ptr+maxBytesToReadr) contains a null byte in the middle, then the + * string will cut short at that byte index (i.e. maxBytesToRead will not + * produce a string of exact length [ptr, ptr+maxBytesToRead)) N.B. mixing + * frequent uses of UTF8ToString() with and without maxBytesToRead may throw + * JS JIT optimizations off, so it is worth to consider consistently using + * one style or the other. + */ + UTF8ToString(ptr: number, maxBytesToRead?: number): string + + /** + * v1.38.27: 02/10/2019 (emscripten) + * -------------------- + * - Remove deprecated Pointer_stringify (use UTF8ToString instead). See #8011 + * + * @param ptr + * @param length + * @constructor + * + * @deprecated use UTF8ToString instead + */ + // eslint-disable-next-line camelcase + Pointer_stringify(ptr: number, length?: number): string + + /** + * Given a string input return the current length of the given UTF8 bytes. + * Used when performing stringToUTF8 since stringToUTF8 will require at most + * str.length*4+1 bytes of space in the HEAP. + * + * @param str The input string. + */ + lengthBytesUTF8(str: string): number + + /** + * Copies the given JavaScript String object str to the Emscripten HEAP at + * address outPtr, null-terminated and encoded in UTF8 form. + * + * The copy will require at most str.length*4+1 bytes of space in the HEAP. + * You can use the function lengthBytesUTF8() to compute the exact amount + * of bytes (excluding the null terminator) needed to encode the string. + * + * @param str A JavaScript String object. + * + * @param outPtr Pointer to data copied from str, encoded in UTF8 format and + * null-terminated. + * + * @param maxBytesToWrite A limit on the number of bytes that this function + * can at most write out. If the string is longer than this, the output is + * truncated. The outputted string will always be null terminated, even if + * truncation occurred, as long as maxBytesToWrite > 0 + */ + stringToUTF8(str: string, outPtr: number, maxBytesToWrite?: number): void + + /** + * Allocates size bytes of uninitialized storage. + * + * If allocation succeeds, returns a pointer that is suitably aligned for any + * object type with fundamental alignment. + * + * @param size number of bytes to allocate + * + * @returns On success, returns the pointer to the beginning of newly + * allocated memory. To avoid a memory leak, the returned pointer must be + * deallocated with free() or realloc(). + */ + _malloc(size: number): number + + /** + * Use addFunction to return an integer value that represents a function + * pointer. Passing that integer to C code then lets it call that value as a + * function pointer, and the JavaScript function you sent to addFunction will + * be called. + * + * when using addFunction on LLVM wasm backend, you need to provide an + * additional second argument, a Wasm function signature string. Each + * character within a signature string represents a type. The first character + * represents the return type of the function, and remaining characters are for + * parameter types. + * + * 'v': void type + * 'i': 32-bit integer type + * 'j': 64-bit integer type (currently does not exist in JavaScript) + * 'f': 32-bit float type + * 'd': 64-bit float type + * + * @param func + * @param signature + */ + addFunction(func: (...args: any[]) => any, signature?: string): number + + /** + * Removes an allocated function by the provided function pointer. + * + * @param funcPtr + */ + removeFunction(funcPtr: number): void + + /** + * Fallback runtime which can contain the add/remove functions + */ + Runtime: { + addFunction(func: (...args: any[]) => any, signature?: string): number + removeFunction(funcPtr: number): void } } -export type GeneratedSources = { - ast: YulAST - contents: string - id: number - language: string - name: string -}[] - -export type FunctionDebugData = Record< - string, - { entryPoint: number | null; id: number | null; parameterSlots: number; returnSlots: number } -> - -export type CompilationError = { - component: 'general' | string - errorCode: string - formattedMessage: string - message: string - severity: 'error' | 'warning' - sourceLocation: { end: number; file: string; start: number } - type: 'Warning' | 'Parser' | string -} +/************************** + * core binding functions + *************************/ -export type ABI = { - inputs: { - internalType: string - name: string - type: string - }[] - - name?: string - outputs?: { internalType: string; name: string; type: string }[] - stateMutability: string - type: string - payable?: boolean - constant?: boolean -} +/** + * Allocates a chunk of memory of size bytes. + * + * Use this function inside callbacks to allocate data that is to be passed to + * the compiler. You may use solidity_free() or solidity_reset() to free this + * memory again, but it is not required as the compiler takes ownership for any + * data passed to it via callbacks. + * + * This function will return NULL if the requested memory region could not be + * allocated. + * + * @param size The size of bytes to be allocated. + */ +export type Alloc = (size: number) => number -type Statement = { - body: { nodeType: string; src: string; statements: Statement[] } - name: string - nodeType: string - parameters: { name: string; nodeType: string; src: string; type: string }[] - src: string -} +/** + * Returns the complete license document. + */ +export type License = () => string | undefined -export type YulAST = { - nodeType: string - src: string - name?: string - statements: Statement[] -} +/** + * This should be called right before each compilation, but not at the end, + * so additional memory can be freed. + */ +export type Reset = () => string -export type DocMethods = Record< - string, - { - details: string - params: Record<string, string> - } -> -export type GasEstimates = Partial<{ - creation: { codeDepositCost: string; executionCost: string; totalCost: string } | string[] - internal: Record<string, string> - external: Record<string, string> -}> - -export type LinkReferences = Record<string, Record<string, { length: number; start: number }[]>> - -export type ContractEVM = { - assembly: string - bytecode: { - functionDebugData: FunctionDebugData - generatedSources: GeneratedSources - linkReferences: LinkReferences - object: string - opcodes: string - sourceMap: string - } - deployedBytecode: { - functionDebugData: FunctionDebugData - generatedSources: GeneratedSources - immutableReferences: Record<string, { length: number; start: number }[]> - linkReferences: LinkReferences - } - gasEstimates: GasEstimates - legacyAssembly: { - '.code': LegacyAssemblyCode[] - '.data': Record< - string, - { - '.auxdata': string - '.code': LegacyAssemblyCode[] - } - > - } - methodIdentifiers: Record<string, string> +/** + * Returns the compiler version. + */ +export type Version = () => string + +// compile binding functions +export type ReadCallbackResult = { contents: string } | { error: string } +export type ReadCallback = (path: string) => ReadCallbackResult +export type Callbacks = { [x: string]: ReadCallback } + +/** + * Compile a single file. + * + * @solidityMaxVersion 0.5.0 + * + * @param input + * @param optimize + */ +export type CompileJson = (input: string, optimize: boolean) => string + +/** + * Compile a single file with a callback. + * + * @solidityMinVersion 0.2.1 + * @solidityMaxVersion 0.5.0 + * + * @param input + * @param optimize + * @param readCallbackPtr + */ +export type CompileJsonCallback = (input: string, optimize: boolean, readCallbackPtr: number) => string + +/** + * Compile multiple files. + * + * @solidityMinVersion 0.1.6 + * @solidityMaxVersion 0.5.0 + * + * @param input + * @param optimize + */ +export type CompileJsonMulti = (input: string, optimize: boolean) => string + +/** + * Will attempt to bind into compileStandard before falling back to solidity_compile. + * compileStandard - solidityMaxVersion 0.5.0 + * + * @solidityMinVersion 0.4.11 + * + * @param input + * @param callbackPtr + * @param contextPtr + */ +export type CompileJsonStandard = (input: string, callbackPtr: number, contextPtr?: number) => string + +/** + * Compile the provided input, using the best case implementation based on the + * current binary. + * + * @param input + * @param readCallback + */ +export type CompileSolidity = (input: string, readCallback?: Callbacks) => string + +export interface CompileBindings { + compileJson: CompileJson + compileJsonCallback: CompileJsonCallback + compileJsonMulti: CompileJsonMulti + compileStandard: CompileJsonStandard } -export type CompiledContract = { - abi: ABI[] - devdoc: { kind: string; methods: DocMethods; version: 1; author: string } - evm: ContractEVM - ewasm: { wasm: string } - metadata: string - storageLayout: { - storage: { - astId: number - contract: string - label: string - offset: number - slot: string - type: string - }[] - types: Record<string, { encoding: string; key?: string; label: string; numberOfBytes: string; value?: string }> - } - userdoc: { kind: string; methods: DocMethods; version: number } +export interface CoreBindings { + alloc: Alloc + license: License + reset: Reset + + version: Version + copyFromCString: (ptr: number) => string + copyToCString: (input: string, ptr: number) => string + + addFunction: (func: (...args: any[]) => any, signature: string) => number + removeFunction: (ptr: number) => void } -export type Output = { - interface: string - error?: CompilationError - errors: CompilationError[] - contracts: { gasEstimates?: GasEstimates } & Record<string, Record<string, CompiledContract>> - sourceList?: string[] - sources?: Record<string, { id: number; AST?: any }> +export interface SupportedMethods { + licenseSupported: boolean + versionSupported: boolean + allocSupported: boolean + resetSupported: boolean + compileJsonSupported: boolean + compileJsonMultiSupported: boolean + compileJsonCallbackSupported: boolean + compileJsonStandardSupported: boolean } -export type Wrapper = Pick<SolcWrapper, 'license' | 'compile' | 'version' | 'loadRemoteVersion'> +export interface Wrapper { + /** + * Returns the complete license document. + */ + license(): string | undefined + + /** + * Returns the compiler version. + */ + version(): string + + /** + * Returns the compiler version as a semver version style. + */ + semver(): string + + /** + * Compile the provided input, using the best case implementation based on the + * current binary. + * + * @param input + * @param readCallback + */ + compile(input: string, readCallback?: Callbacks): string + + lowlevel: { + compileSingle?: CompileJson + compileMulti?: CompileJsonMulti + compileCallback?: CompileJsonCallback + compileStandard?: CompileJsonStandard + } -export type CoreBindings = - & Omit<Bindings, 'versionToSemver' | 'isVersion6OrNewer' | 'copyFromCString' | 'copyToCString'> - & { - copyFromCString: (ptr: number) => string - copyToCString: (input: string, ptr: number) => string + features: { + legacySingleInput: boolean + multipleInputs: boolean + importCallback: boolean + nativeStandardJSON: boolean } -export type Callbacks = Partial<{ - import: (data: unknown) => void - smtSolver: (data: string) => void -}> + loadRemoteVersion(version: string, callback: (error?: Error, solc?: SolJson) => void): void + + setupMethods(soljson: SolJson): Wrapper +} From e94b35cba5c7e92a4cabb2d9ab3598edba3c6ed6 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 00:09:30 +0200 Subject: [PATCH 04/16] get rid of more fallbacks and remove duplicate types --- bindings/compile.ts | 4 ++-- bindings/core.ts | 16 +++++++++------- bindings/index.ts | 4 +--- types.ts | 8 -------- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/bindings/compile.ts b/bindings/compile.ts index fea2250..d9c0ac6 100644 --- a/bindings/compile.ts +++ b/bindings/compile.ts @@ -111,11 +111,11 @@ function wrapCallbackWithKind<Arg extends string>( ) { assert(typeof callback === 'function', 'Invalid callback specified.') - return function (context: 0, kind: string, data: string, contents: string, error: string) { + return function (context: 0, kind: number, data: number, contents: number, error: number) { // Must be a null pointer. assert(context === 0, 'Callback context must be null.') console.log({ kind, data }) - const result = callback(coreBindings.copyFromCString(kind), coreBindings.copyFromCString(data)) + const result = callback(coreBindings.copyFromCString(kind) as Arg, coreBindings.copyFromCString(data) as Arg) if (typeof result.contents === 'string') { coreBindings.copyToCString(result.contents, contents) } diff --git a/bindings/core.ts b/bindings/core.ts index e80cfdb..519b63a 100644 --- a/bindings/core.ts +++ b/bindings/core.ts @@ -1,10 +1,10 @@ import { isNil } from '../common.ts' -import { type CoreBindings, type License, Reset, type SolJson } from 'solc/types' +import { Alloc, type CoreBindings, type License, Reset, type SolJson } from 'solc/types' import { bindSolcMethod, bindSolcMethodWithFallbackFunc } from './helpers.ts' export function setupCore(solJson: SolJson): CoreBindings { const core = { - alloc: bindAlloc<(n: number) => number>(solJson), + alloc: bindAlloc(solJson), license: bindLicense(solJson), version: bindVersion<() => string>(solJson), reset: bindReset(solJson), @@ -36,8 +36,8 @@ export function setupCore(solJson: SolJson): CoreBindings { * * @param solJson The Emscripten compiled Solidity object. */ -function bindAlloc<T>(solJson: SolJson) { - const allocBinding = bindSolcMethod<T>( +function bindAlloc(solJson: SolJson) { + const allocBinding = bindSolcMethod<Alloc>( solJson, 'solidity_alloc', 'number', @@ -124,13 +124,15 @@ function bindReset(solJson: SolJson) { * @param str The source string being copied to a C string. * @param ptr The pointer location where the C string will be set. */ -function unboundCopyToCString(solJson: SolJson, alloc: (n: number) => number, str: string, ptr: number) { +function unboundCopyToCString(solJson: SolJson, alloc: Alloc, str: string, ptr: number) { const length = solJson.lengthBytesUTF8(str) const buffer = alloc(length + 1) solJson.stringToUTF8(str, buffer, length + 1) solJson.setValue(ptr, buffer, '*') + + return str } /** @@ -145,9 +147,9 @@ function unboundCopyFromCString(solJson: SolJson, ptr: number) { } function unboundAddFunction(solJson: SolJson, func: (...args: unknown[]) => unknown, signature?: string) { - return (solJson.addFunction || solJson.Runtime.addFunction)(func, signature) + return solJson.addFunction(func, signature) } function unboundRemoveFunction(solJson: SolJson, ptr: number) { - return (solJson.removeFunction || solJson.Runtime.removeFunction)(ptr) + return solJson.removeFunction(ptr) } diff --git a/bindings/index.ts b/bindings/index.ts index 58350b2..f4c5934 100644 --- a/bindings/index.ts +++ b/bindings/index.ts @@ -1,4 +1,4 @@ -import { SolJson } from '../deps.ts' +import { SolJson } from 'solc/types' import { setupCompile } from './compile.ts' import { setupCore } from './core.ts' import { getSupportedMethods } from './helpers.ts' @@ -12,9 +12,7 @@ export default function setupBindings(solJson: SolJson) { return { methodFlags, - coreBindings, - compileBindings, } } diff --git a/types.ts b/types.ts index 110d52b..2dce6bf 100644 --- a/types.ts +++ b/types.ts @@ -181,14 +181,6 @@ export interface SolJson { * @param funcPtr */ removeFunction(funcPtr: number): void - - /** - * Fallback runtime which can contain the add/remove functions - */ - Runtime: { - addFunction(func: (...args: any[]) => any, signature?: string): number - removeFunction(funcPtr: number): void - } } /************************** From 29e4e21e58aacf01238aa8e357e0d186f74955f4 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 00:45:20 +0200 Subject: [PATCH 05/16] improve output types --- mod_test.ts | 1 + types.ts | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/mod_test.ts b/mod_test.ts index 73364ea..ff2494b 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -44,6 +44,7 @@ describe('solc/wrapper.ts', () => { }, } const output: Output = JSON.parse(solc.compile(JSON.stringify(input))) + expect(output.sources!['Hello.sol'].id).toEqual(0) expect(output.contracts!['Hello.sol']['HelloWorld'].abi).toEqual([ { diff --git a/types.ts b/types.ts index 2dce6bf..384665e 100644 --- a/types.ts +++ b/types.ts @@ -351,3 +351,152 @@ export interface Wrapper { setupMethods(soljson: SolJson): Wrapper } + +export interface Input { + language: 'Solidity' | 'Yul' + sources: { [contractName: string]: { content: string } } + settings?: { + outputSelection?: { '*'?: { '*'?: string[] } } + optimizer?: { + enabled?: boolean + runs?: number + } + evmVersion?: string + libraries?: { [libraryName: string]: string } + remappings?: string[] + } +} + +interface ContractABI { + inputs: { internalType: string; name: string; type: string; indexed?: boolean }[] + name: string + outputs: { internalType: string; name: string; type: string }[] + stateMutability: string + type: string +} + +interface DevDoc { + kind: 'dev' + methods: Record<string, any> + version: number + details: string +} + +interface UserDoc { + kind: 'user' + methods: Record<string, any> + version: number +} + +interface AST { + nativeSrc: string + nodeType: string + src: string + statements: { body?: AST; name: string; nativeSrc: string; nodeType: string }[] +} + +interface GeneratedSource { + ast: AST + contents: string + id: number + language: 'Yul' + name: `${string}.yul` +} + +interface Bytecode { + linkReferences: LinkReferences + object: string + generatedSources: GeneratedSource[] +} + +interface GasEstimates { + creation: { + codeDepositCost: string + executionCost: string + totalCost: string + } + external: { + [functionName: string]: string + } +} + +interface LegacyAssemblyItem { + begin: number + end: number + name: string + source: number + value: string +} + +interface LegacyAssembly { + '.code': LegacyAssemblyItem[] + '.data': { + '0': { + '.auxdata': string + '.code': LegacyAssemblyItem[] + } + } + sourceList: string[] +} + +interface EVM { + assembly: string + bytecode: Bytecode + deployedBytecode: Bytecode + gasEstimates: GasEstimates + legacyAssembly: LegacyAssembly + methodIdentifiers: Record<string, string> +} + +interface Ewasm { + wasm: string +} + +interface StorageItem { + astId: number + contract: string + label: string + offset: number + slot: string + type: string +} + +interface StorageType { + encoding: string + label: string + numberOfBytes: string +} + +interface StorageLayout { + storage: StorageItem[] + types: Record<string, StorageType> +} + +interface Contract { + abi: ContractABI[] + devdoc: DevDoc + evm: EVM + ewasm: Ewasm + metadata: string + storageLayout: StorageLayout + transientStorageLayout?: StorageLayout + userdoc: UserDoc +} + +interface Contracts { + [contractName: string]: { + [contractInstance: string]: Contract + } +} + +interface Sources { + [sourceName: string]: { + id: number + } +} + +export interface Output { + sources: Sources + contracts: Contracts + errors: unknown[] +} From e8deaf1652824510b67bdbbd9076ff07a6be709c Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:07:50 +0200 Subject: [PATCH 06/16] improve types --- bindings/compile.ts | 24 ++++++++++++++++-------- mod.ts | 8 +------- types.ts | 7 ------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/bindings/compile.ts b/bindings/compile.ts index d9c0ac6..a246eb3 100644 --- a/bindings/compile.ts +++ b/bindings/compile.ts @@ -2,9 +2,17 @@ import assert from 'node:assert' import { isNil } from '../common.ts' import { bindSolcMethod } from './helpers.ts' -import { Callbacks, CoreBindings, ReadCallback, SolJson } from 'solc/types' - -export function setupCompile(solJson: SolJson, core: CoreBindings) { +import { + Callbacks, + CompileBindings, + CompileJson, + CompileJsonCallback, + CoreBindings, + ReadCallback, + SolJson, +} from 'solc/types' + +export function setupCompile(solJson: SolJson, core: CoreBindings): CompileBindings { return { compileJson: bindCompileJson(solJson), compileJsonCallback: bindCompileJsonCallback(solJson, core), @@ -23,7 +31,7 @@ export function setupCompile(solJson: SolJson, core: CoreBindings) { * * @param solJson The Emscripten compiled Solidity object. */ -function bindCompileJson(solJson: SolJson) { +const bindCompileJson = (solJson: SolJson): CompileJson => { return bindSolcMethod( solJson, 'compileJSON', @@ -39,7 +47,7 @@ function bindCompileJson(solJson: SolJson) { * * @param solJson The Emscripten compiled Solidity object. */ -function bindCompileJsonMulti(solJson: SolJson) { +function bindCompileJsonMulti(solJson: SolJson): CompileMulti { return bindSolcMethod( solJson, 'compileJSONMulti', @@ -56,7 +64,7 @@ function bindCompileJsonMulti(solJson: SolJson) { * @param solJson The Emscripten compiled Solidity object. * @param coreBindings The core bound Solidity methods. */ -function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings) { +function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings): CompileJsonCallback { const compileInternal = bindSolcMethod<(arg0: string, arg1: number, arg2?: number) => string>( solJson, 'compileJSONCallback', @@ -67,7 +75,7 @@ function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings) { if (isNil(compileInternal)) return null - return function (input: string, optimize: number, readCallback: ReadCallback) { + return function (input: string, optimize: boolean, readCallback: ReadCallback) { return runWithCallbacks(solJson, coreBindings, readCallback, compileInternal, [input, optimize]) } } @@ -79,7 +87,7 @@ function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings) { * @param solJson The Emscripten compiled Solidity object. * @param coreBindings The core bound Solidity methods. */ -function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings) { +function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings): CompileStandard { let boundFunctionStandard = null let boundFunctionSolidity: ((jsontext: string, ptr?: number) => string) | null = null diff --git a/mod.ts b/mod.ts index ee7eb29..f028d97 100644 --- a/mod.ts +++ b/mod.ts @@ -1,15 +1,10 @@ import setupBindings from './bindings/index.ts' -import { CompileBindings, SolJson } from './deps.ts' -import type { Wrapper } from './types.ts' +import type { CompileBindings, SolJson, Wrapper } from 'solc/types' function compileStandardWrapper(compile: CompileBindings, inputRaw: string, readCallback: unknown) { return compile.compileStandard(inputRaw, readCallback as number) } -if (!globalThis.__dirname) { - globalThis.__dirname = import.meta.url -} - /** * Wrap Solidity compiler into a JS interface * @param soljson WebAssembly compiler module @@ -22,6 +17,5 @@ export function wrapper(soljson: SolJson): Wrapper { license: coreBindings.license, // @ts-ignore this stuff compile: compileStandardWrapper.bind(this, compileBindings), - loadRemoteVersion: () => void 0, } } diff --git a/types.ts b/types.ts index 384665e..ff9a860 100644 --- a/types.ts +++ b/types.ts @@ -319,11 +319,6 @@ export interface Wrapper { */ version(): string - /** - * Returns the compiler version as a semver version style. - */ - semver(): string - /** * Compile the provided input, using the best case implementation based on the * current binary. @@ -347,8 +342,6 @@ export interface Wrapper { nativeStandardJSON: boolean } - loadRemoteVersion(version: string, callback: (error?: Error, solc?: SolJson) => void): void - setupMethods(soljson: SolJson): Wrapper } From 6667eb159f8de46c803d8ee8a0c0686bccfd38d0 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:26:52 +0200 Subject: [PATCH 07/16] remove legacy pre 0.5 solidity compile methods --- bindings/compile.ts | 92 +++++---------------------------------------- bindings/helpers.ts | 3 -- deno.json | 6 +-- types.ts | 52 ------------------------- 4 files changed, 12 insertions(+), 141 deletions(-) diff --git a/bindings/compile.ts b/bindings/compile.ts index a246eb3..e8b2c68 100644 --- a/bindings/compile.ts +++ b/bindings/compile.ts @@ -1,22 +1,10 @@ import assert from 'node:assert' -import { isNil } from '../common.ts' import { bindSolcMethod } from './helpers.ts' -import { - Callbacks, - CompileBindings, - CompileJson, - CompileJsonCallback, - CoreBindings, - ReadCallback, - SolJson, -} from 'solc/types' +import { Callbacks, CompileBindings, CompileJsonStandard, CoreBindings, ReadCallback, SolJson } from 'solc/types' export function setupCompile(solJson: SolJson, core: CoreBindings): CompileBindings { return { - compileJson: bindCompileJson(solJson), - compileJsonCallback: bindCompileJsonCallback(solJson, core), - compileJsonMulti: bindCompileJsonMulti(solJson), compileStandard: bindCompileStandard(solJson, core), } } @@ -25,61 +13,6 @@ export function setupCompile(solJson: SolJson, core: CoreBindings): CompileBindi * COMPILE **********************/ -/** - * Returns a binding to the solidity compileJSON method. - * input (text), optimize (bool) -> output (jsontext) - * - * @param solJson The Emscripten compiled Solidity object. - */ -const bindCompileJson = (solJson: SolJson): CompileJson => { - return bindSolcMethod( - solJson, - 'compileJSON', - 'string', - ['string', 'number'], - null, - ) -} - -/** - * Returns a binding to the solidity compileJSONMulti method. - * input (jsontext), optimize (bool) -> output (jsontext) - * - * @param solJson The Emscripten compiled Solidity object. - */ -function bindCompileJsonMulti(solJson: SolJson): CompileMulti { - return bindSolcMethod( - solJson, - 'compileJSONMulti', - 'string', - ['string', 'number'], - null, - ) -} - -/** - * Returns a binding to the solidity compileJSONCallback method. - * input (jsontext), optimize (bool), callback (ptr) -> output (jsontext) - * - * @param solJson The Emscripten compiled Solidity object. - * @param coreBindings The core bound Solidity methods. - */ -function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings): CompileJsonCallback { - const compileInternal = bindSolcMethod<(arg0: string, arg1: number, arg2?: number) => string>( - solJson, - 'compileJSONCallback', - 'string', - ['string', 'number', 'number'], - null, - ) - - if (isNil(compileInternal)) return null - - return function (input: string, optimize: boolean, readCallback: ReadCallback) { - return runWithCallbacks(solJson, coreBindings, readCallback, compileInternal, [input, optimize]) - } -} - /** * Returns a binding to the solidity solidity_compile method. * input (jsontext), callback (optional >= v6 only - ptr) -> output (jsontext) @@ -87,12 +20,9 @@ function bindCompileJsonCallback(solJson: SolJson, coreBindings: CoreBindings): * @param solJson The Emscripten compiled Solidity object. * @param coreBindings The core bound Solidity methods. */ -function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings): CompileStandard { - let boundFunctionStandard = null - let boundFunctionSolidity: ((jsontext: string, ptr?: number) => string) | null = null - +function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings): CompileJsonStandard { // input (jsontext), callback (ptr), callback_context (ptr) -> output (jsontext) - boundFunctionSolidity = bindSolcMethod( + const boundFunctionSolidity: (jsontext: string, ptr?: number) => string = bindSolcMethod( solJson, 'solidity_compile', 'string', @@ -100,13 +30,11 @@ function bindCompileStandard(solJson: SolJson, coreBindings: CoreBindings): Comp null, ) - if (!isNil(boundFunctionSolidity)) { - boundFunctionStandard = function (input: string, callbacks: Callbacks) { - return runWithCallbacks(solJson, coreBindings, callbacks, boundFunctionSolidity, [input]) - } + const boundFunctionStandard = function (input: string, callbacks: Callbacks) { + return runWithCallbacks(solJson, coreBindings, callbacks, boundFunctionSolidity, [input]) } - return boundFunctionStandard + return boundFunctionStandard as unknown as CompileJsonStandard } /********************** @@ -137,9 +65,9 @@ function wrapCallbackWithKind<Arg extends string>( function runWithCallbacks<Args extends unknown[]>( _solJson: SolJson, coreBindings: CoreBindings, - callbacks: Callbacks | ReadCallback, - compile: (...args: Args) => void, - args: Args, + callbacks?: Callbacks | ReadCallback, + compile?: (...args: Args) => void, + args: Args = [] as unknown as Args, ) { if (callbacks) { assert(typeof callbacks === 'object', 'Invalid callback object specified.') @@ -187,7 +115,7 @@ function runWithCallbacks<Args extends unknown[]>( // Callback context. args.push(null) - output = compile(...args) + output = compile?.(...args) } finally { coreBindings.removeFunction(cb) } diff --git a/bindings/helpers.ts b/bindings/helpers.ts index 5248555..e0edbed 100644 --- a/bindings/helpers.ts +++ b/bindings/helpers.ts @@ -38,9 +38,6 @@ export function getSupportedMethods(solJson: SolJson) { versionSupported: anyMethodExists(solJson, 'solidity_version'), allocSupported: anyMethodExists(solJson, 'solidity_alloc'), resetSupported: anyMethodExists(solJson, 'solidity_reset'), - compileJsonSupported: anyMethodExists(solJson, 'compileJSON'), - compileJsonMultiSupported: anyMethodExists(solJson, 'compileJSONMulti'), - compileJsonCallbackSuppported: anyMethodExists(solJson, 'compileJSONCallback'), compileJsonStandardSupported: anyMethodExists(solJson, 'compileStandard', 'solidity_compile'), } } diff --git a/deno.json b/deno.json index 59bb88c..06fdc82 100644 --- a/deno.json +++ b/deno.json @@ -1,9 +1,7 @@ { "lint": { - "files": { - "include": ["./**/*.ts"], - "exclude": ["./**/*.js"] - }, + "include": ["./**/*.ts"], + "exclude": ["./**/*.js"], "rules": { "exclude": ["no-explicit-any"] } diff --git a/types.ts b/types.ts index ff9a860..b589d0f 100644 --- a/types.ts +++ b/types.ts @@ -223,39 +223,6 @@ export type ReadCallbackResult = { contents: string } | { error: string } export type ReadCallback = (path: string) => ReadCallbackResult export type Callbacks = { [x: string]: ReadCallback } -/** - * Compile a single file. - * - * @solidityMaxVersion 0.5.0 - * - * @param input - * @param optimize - */ -export type CompileJson = (input: string, optimize: boolean) => string - -/** - * Compile a single file with a callback. - * - * @solidityMinVersion 0.2.1 - * @solidityMaxVersion 0.5.0 - * - * @param input - * @param optimize - * @param readCallbackPtr - */ -export type CompileJsonCallback = (input: string, optimize: boolean, readCallbackPtr: number) => string - -/** - * Compile multiple files. - * - * @solidityMinVersion 0.1.6 - * @solidityMaxVersion 0.5.0 - * - * @param input - * @param optimize - */ -export type CompileJsonMulti = (input: string, optimize: boolean) => string - /** * Will attempt to bind into compileStandard before falling back to solidity_compile. * compileStandard - solidityMaxVersion 0.5.0 @@ -278,9 +245,6 @@ export type CompileJsonStandard = (input: string, callbackPtr: number, contextPt export type CompileSolidity = (input: string, readCallback?: Callbacks) => string export interface CompileBindings { - compileJson: CompileJson - compileJsonCallback: CompileJsonCallback - compileJsonMulti: CompileJsonMulti compileStandard: CompileJsonStandard } @@ -327,22 +291,6 @@ export interface Wrapper { * @param readCallback */ compile(input: string, readCallback?: Callbacks): string - - lowlevel: { - compileSingle?: CompileJson - compileMulti?: CompileJsonMulti - compileCallback?: CompileJsonCallback - compileStandard?: CompileJsonStandard - } - - features: { - legacySingleInput: boolean - multipleInputs: boolean - importCallback: boolean - nativeStandardJSON: boolean - } - - setupMethods(soljson: SolJson): Wrapper } export interface Input { From 6551c64258c036bd916a03a03626dd5404349113 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:33:15 +0200 Subject: [PATCH 08/16] remove legacy fallback code and add tests for isNil --- bindings/core.ts | 6 ------ common.ts | 13 ------------- common_test.ts | 12 ++++++++++++ deno.lock | 14 +++++++++++++- mod_test.ts | 2 +- 5 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 common_test.ts diff --git a/bindings/core.ts b/bindings/core.ts index 519b63a..e98b48b 100644 --- a/bindings/core.ts +++ b/bindings/core.ts @@ -45,12 +45,6 @@ function bindAlloc(solJson: SolJson) { null, ) - // the fallback malloc is not a cwrap function and should just be returned - // directly in-case the alloc binding could not happen. - if (isNil(allocBinding)) { - return solJson._malloc - } - return allocBinding } diff --git a/common.ts b/common.ts index 73e442a..12f42ac 100644 --- a/common.ts +++ b/common.ts @@ -1,14 +1 @@ -export const formatFatalError = (message: string) => - JSON.stringify({ - errors: [ - { - type: 'JSONError', - component: 'solcjs', - severity: 'error', - message: message, - formattedMessage: 'Error: ' + message, - }, - ], - }) - export const isNil = (value: unknown): value is null => value == null diff --git a/common_test.ts b/common_test.ts new file mode 100644 index 0000000..81110f1 --- /dev/null +++ b/common_test.ts @@ -0,0 +1,12 @@ +import { isNil } from './common.ts' +import { expect } from '@std/expect' +import { describe, it } from '@std/testing/bdd' + +describe('common.ts', () => { + it('isNil', () => { + expect(isNil(null)).toBe(true) + expect(isNil(undefined)).toBe(true) + expect(isNil(0)).toBe(false) + expect(isNil('')).toBe(false) + }) +}) diff --git a/deno.lock b/deno.lock index 20d6003..4122ce4 100644 --- a/deno.lock +++ b/deno.lock @@ -7,7 +7,8 @@ "jsr:@std/expect@^1.0.13": "1.0.13", "jsr:@std/internal@^1.0.5": "1.0.5", "jsr:@std/io@~0.225.2": "0.225.2", - "jsr:@std/testing@^1.0.9": "1.0.9" + "jsr:@std/testing@^1.0.9": "1.0.9", + "npm:@types/node@*": "22.12.0" }, "jsr": { "@std/assert@1.0.11": { @@ -43,6 +44,17 @@ ] } }, + "npm": { + "@types/node@22.12.0": { + "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "dependencies": [ + "undici-types" + ] + }, + "undici-types@6.20.0": { + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + } + }, "workspace": { "dependencies": [ "jsr:@std/expect@^1.0.13", diff --git a/mod_test.ts b/mod_test.ts index ff2494b..7c9753b 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -18,7 +18,7 @@ contract HelloWorld { } ` -describe('solc/wrapper.ts', () => { +describe('Wrapper', () => { let solc: Wrapper beforeAll(async () => { await download('./soljson_test.cjs', '0.8.18') From be09f16994bbf232c3ebaf429908fc792e44a6f7 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:36:40 +0200 Subject: [PATCH 09/16] prepare for jsr publish --- deno.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/deno.json b/deno.json index 06fdc82..1040322 100644 --- a/deno.json +++ b/deno.json @@ -29,5 +29,9 @@ "tasks": { "test": "deno test --no-check --allow-net --allow-read --allow-write --coverage=coverage", "cov": "deno coverage coverage --lcov > coverage.lcov" - } + }, + "name": "@deno-web3/solc", + "version": "3.0.0", + "license": "MIT", + "exports": "./mod.ts" } From 3e6a318b48d14bc2c5cf246f6c8cc67c82beb6af Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:43:33 +0200 Subject: [PATCH 10/16] readme update --- README.md | 11 +++++------ examples/erc20/mod.ts | 2 +- examples/with-library/mod.ts | 2 +- logo.png | Bin 0 -> 87285 bytes 4 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 logo.png diff --git a/README.md b/README.md index 602fb0c..89f7cfc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ <div align="center"> -<img alt="logo" height="250px" src="https://bafkreicd4u5jhqcnhztqhi3dkvefx3ccooimkqca33ipjo4njyzfus5nfu.ipfs.dweb.link" /> +<img alt="logo" height="250px" src="./logo.png" /> # solc -[![nest badge][nest-badge]](https://nest.land/package/solc) [![GitHub Workflow Status][gh-actions-img]][github-actions] +[![GitHub Workflow Status][gh-actions-img]][github-actions] [![Codecov][cov-badge-url]][cov-url] [![][code-quality-img]][code-quality] </div> @@ -22,9 +22,9 @@ See [solc-js README](https://github.com/ethereum/solc-js#readme) and [Deno doc]( ## Example ```ts -import { wrapper } from 'https://deno.land/x/solc/mod.ts' -import { Input } from 'https://deno.land/x/solc/types.ts' -import { download } from 'https://deno.land/x/solc/download.ts' +import { wrapper } from '@deno-web3/solc' +import { Input } from '@deno-web3/solc/types.ts' +import { download } from '@deno-web3/solc/download.ts' import { createRequire } from 'node:module' // Download latest Solidity compiler @@ -64,7 +64,6 @@ deno run --allow-net --allow-read --allow-write mod.ts [code-quality-img]: https://img.shields.io/codefactor/grade/github/deno-web3/solc?style=for-the-badge&color=626890& [code-quality]: https://www.codefactor.io/repository/github/deno-web3/solc -[nest-badge]: https://img.shields.io/badge/publushed%20on-nest.land-626890?style=for-the-badge [cov-badge-url]: https://img.shields.io/coveralls/github/deno-web3/solc?style=for-the-badge&color=626890& [cov-url]: https://coveralls.io/github/deno-web3/solc [github-actions]: https://github.com/tinyhttp/deno-web3/solc diff --git a/examples/erc20/mod.ts b/examples/erc20/mod.ts index 0a7cb17..3cce874 100644 --- a/examples/erc20/mod.ts +++ b/examples/erc20/mod.ts @@ -1,5 +1,5 @@ import { wrapper } from 'solc' -import { Input } from 'solc/types' +import type { Input } from 'solc/types' import { download } from 'solc/download' import { exists } from '../../helpers_test.ts' diff --git a/examples/with-library/mod.ts b/examples/with-library/mod.ts index 93b0a09..f87a6f5 100644 --- a/examples/with-library/mod.ts +++ b/examples/with-library/mod.ts @@ -1,5 +1,5 @@ import { wrapper } from 'solc' -import { Input, Output } from 'solc/types' +import type { Input, Output } from 'solc/types' import { download } from 'solc/download' import { createRequire } from '../../helpers_test.ts' import { exists } from '../../helpers_test.ts' diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..180888d230fa78aa4a91a7064b4e64f5c689dfb7 GIT binary patch literal 87285 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�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 M07*qoM6N<$g7gp20{{R3 literal 0 HcmV?d00001 From b6c6346077af544227bf689d68715c0d36c3ab3b Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:46:37 +0200 Subject: [PATCH 11/16] add exports --- README.md | 4 ++-- deno.json | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 89f7cfc..66d6813 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ See [solc-js README](https://github.com/ethereum/solc-js#readme) and [Deno doc]( ```ts import { wrapper } from '@deno-web3/solc' -import { Input } from '@deno-web3/solc/types.ts' -import { download } from '@deno-web3/solc/download.ts' +import { Input } from '@deno-web3/solc/types' +import { download } from '@deno-web3/solc/download' import { createRequire } from 'node:module' // Download latest Solidity compiler diff --git a/deno.json b/deno.json index 1040322..e8f7436 100644 --- a/deno.json +++ b/deno.json @@ -33,5 +33,9 @@ "name": "@deno-web3/solc", "version": "3.0.0", "license": "MIT", - "exports": "./mod.ts" + "exports": { + "./": "./mod.ts", + "./download": "./download.ts", + "./types": "./types.ts" + } } From 189f9b1e615b21ce3f4bf16611ef0181934e6dd4 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:47:01 +0200 Subject: [PATCH 12/16] oops --- deno.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.json b/deno.json index e8f7436..8c25a05 100644 --- a/deno.json +++ b/deno.json @@ -34,7 +34,7 @@ "version": "3.0.0", "license": "MIT", "exports": { - "./": "./mod.ts", + ".": "./mod.ts", "./download": "./download.ts", "./types": "./types.ts" } From 246d85139479cc4ba4b03befcdf104eb554ec475 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:48:12 +0200 Subject: [PATCH 13/16] update ci --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ae70daf..aa61812 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,18 +12,18 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-deno-${{ hashFiles('**/*') }} restore-keys: ${{ runner.os }}-deno- path: /home/runner/.cache/deno/deps/https/deno.land - - uses: denoland/setup-deno@v1 + - uses: denoland/setup-deno@v2 with: - deno-version: v1.x + deno-version: v2.x - name: fetch any uncached dependencies run: | From 2b98a6055d6dc1f17f6d0b90f30045cd1b56b1e7 Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:52:11 +0200 Subject: [PATCH 14/16] better types --- bindings/helpers.ts | 6 +++--- examples/erc20/mod.ts | 4 ++-- types.ts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bindings/helpers.ts b/bindings/helpers.ts index e0edbed..64b5509 100644 --- a/bindings/helpers.ts +++ b/bindings/helpers.ts @@ -1,5 +1,5 @@ import { isNil } from '../common.ts' -import { SolJson } from 'solc/types' +import type { SolJson } from 'solc/types' export function bindSolcMethod<T>( solJson: SolJson, @@ -8,7 +8,7 @@ export function bindSolcMethod<T>( args: string[], defaultValue?: unknown, ): T { - if (isNil((solJson as any)[`_${method}`]) && defaultValue !== undefined) { + if (isNil(solJson[`_${method}` as keyof typeof solJson]) && defaultValue !== undefined) { return defaultValue as T } @@ -43,5 +43,5 @@ export function getSupportedMethods(solJson: SolJson) { } function anyMethodExists(solJson: SolJson, ...names: string[]) { - return names.some((name) => !isNil((solJson as any)[`_${name}`])) + return names.some((name) => !isNil(solJson[`_${name}` as keyof typeof solJson])) } diff --git a/examples/erc20/mod.ts b/examples/erc20/mod.ts index 3cce874..eb91182 100644 --- a/examples/erc20/mod.ts +++ b/examples/erc20/mod.ts @@ -1,5 +1,5 @@ import { wrapper } from 'solc' -import type { Input } from 'solc/types' +import type { Input, Output } from 'solc/types' import { download } from 'solc/download' import { exists } from '../../helpers_test.ts' @@ -31,6 +31,6 @@ const input: Input = { }, } -const result = JSON.parse(solc.compile(JSON.stringify(input))) +const result = JSON.parse(solc.compile(JSON.stringify(input))) as Output console.log(result) diff --git a/types.ts b/types.ts index b589d0f..52d3920 100644 --- a/types.ts +++ b/types.ts @@ -318,14 +318,14 @@ interface ContractABI { interface DevDoc { kind: 'dev' - methods: Record<string, any> + methods: Record<string, unknown> version: number details: string } interface UserDoc { kind: 'user' - methods: Record<string, any> + methods: Record<string, unknown> version: number } From e9dca902b70b045ec6129dd15f158e9b68b2bd4e Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:56:51 +0200 Subject: [PATCH 15/16] fix from `deno lint` --- bindings/compile.ts | 2 +- bindings/core.ts | 3 +-- bindings/index.ts | 2 +- download.ts | 2 +- types.ts | 8 ++++---- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/bindings/compile.ts b/bindings/compile.ts index e8b2c68..4c4512f 100644 --- a/bindings/compile.ts +++ b/bindings/compile.ts @@ -1,7 +1,7 @@ import assert from 'node:assert' import { bindSolcMethod } from './helpers.ts' -import { Callbacks, CompileBindings, CompileJsonStandard, CoreBindings, ReadCallback, SolJson } from 'solc/types' +import type { Callbacks, CompileBindings, CompileJsonStandard, CoreBindings, ReadCallback, SolJson } from 'solc/types' export function setupCompile(solJson: SolJson, core: CoreBindings): CompileBindings { return { diff --git a/bindings/core.ts b/bindings/core.ts index e98b48b..caba252 100644 --- a/bindings/core.ts +++ b/bindings/core.ts @@ -1,5 +1,4 @@ -import { isNil } from '../common.ts' -import { Alloc, type CoreBindings, type License, Reset, type SolJson } from 'solc/types' +import type { Alloc, CoreBindings, License, Reset, SolJson } from 'solc/types' import { bindSolcMethod, bindSolcMethodWithFallbackFunc } from './helpers.ts' export function setupCore(solJson: SolJson): CoreBindings { diff --git a/bindings/index.ts b/bindings/index.ts index f4c5934..1705d42 100644 --- a/bindings/index.ts +++ b/bindings/index.ts @@ -1,4 +1,4 @@ -import { SolJson } from 'solc/types' +import type { SolJson } from 'solc/types' import { setupCompile } from './compile.ts' import { setupCore } from './core.ts' import { getSupportedMethods } from './helpers.ts' diff --git a/download.ts b/download.ts index 5cfe02d..2e55495 100644 --- a/download.ts +++ b/download.ts @@ -5,7 +5,7 @@ import { copy, readerFromStreamReader } from './deps.ts' * @param path download destination * @param version compiler version. if not specified, latest is downloaded */ -export const download = async (path = './soljson.cjs', version?: string) => { +export const download = async (path = './soljson.cjs', version?: string): Promise<string> => { console.log(`Fetching releases...`) const { releases, latestRelease } = (await fetch('https://binaries.soliditylang.org/emscripten-wasm32/list.json').then((res) => res.json())) as { diff --git a/types.ts b/types.ts index 52d3920..937d3a6 100644 --- a/types.ts +++ b/types.ts @@ -73,7 +73,7 @@ export interface SolJson { * used in SAFE_HEAP compilation mode, where it can help avoid infinite recursion * in some specialist use cases. */ - setValue(ptr: number, value: any, type: string, noSafe?: boolean): void + setValue(ptr: number, value: unknown, type: string, noSafe?: boolean): void /** * Given a pointer ptr to a null-terminated UTF8-encoded string in the @@ -173,14 +173,14 @@ export interface SolJson { * @param func * @param signature */ - addFunction(func: (...args: any[]) => any, signature?: string): number + addFunction: CoreBindings['addFunction'] /** * Removes an allocated function by the provided function pointer. * * @param funcPtr */ - removeFunction(funcPtr: number): void + removeFunction: CoreBindings['removeFunction'] } /************************** @@ -257,7 +257,7 @@ export interface CoreBindings { copyFromCString: (ptr: number) => string copyToCString: (input: string, ptr: number) => string - addFunction: (func: (...args: any[]) => any, signature: string) => number + addFunction: <Func extends (...args: any[]) => any>(func: Func, signature?: string) => number removeFunction: (ptr: number) => void } From ba97409cf20f8dc824058cfac8004e80b4f22d3e Mon Sep 17 00:00:00 2001 From: v1rtl <hi@v1rtl.site> Date: Thu, 27 Feb 2025 22:59:03 +0200 Subject: [PATCH 16/16] ignore --- types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types.ts b/types.ts index 937d3a6..6a52059 100644 --- a/types.ts +++ b/types.ts @@ -257,7 +257,7 @@ export interface CoreBindings { copyFromCString: (ptr: number) => string copyToCString: (input: string, ptr: number) => string - addFunction: <Func extends (...args: any[]) => any>(func: Func, signature?: string) => number + addFunction: <Func extends (...args: any[]) => void>(func: Func, signature?: string) => number removeFunction: (ptr: number) => void }