From cac64be5a5a599fd162d2d278cbcbfe0c156f29b Mon Sep 17 00:00:00 2001 From: Agustincito Date: Thu, 12 Feb 2026 17:10:16 -0300 Subject: [PATCH 1/3] Chore: Add runner target --- packages/cli/package.json | 8 ++++ packages/cli/src/commands/compile.ts | 62 +++++++++++++++++++++++++ packages/cli/src/lib/ManifestHandler.ts | 19 +------- packages/cli/src/validators.ts | 2 +- packages/lib-ts/constants.ts | 4 ++ packages/lib-ts/package.json | 5 ++ 6 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 packages/lib-ts/constants.ts diff --git a/packages/cli/package.json b/packages/cli/package.json index e99e3dd3..10fd8eac 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -49,6 +49,14 @@ "ts-node": "^10.9.2", "typescript": "^5.8.3" }, + "peerDependencies": { + "@mimicprotocol/lib-ts": ">=0.0.1-rc.38" + }, + "peerDependenciesMeta": { + "@mimicprotocol/lib-ts": { + "optional": false + } + }, "oclif": { "bin": "mimic", "commands": "./dist/commands", diff --git a/packages/cli/src/commands/compile.ts b/packages/cli/src/commands/compile.ts index ee2f08dc..05aa4be1 100644 --- a/packages/cli/src/commands/compile.ts +++ b/packages/cli/src/commands/compile.ts @@ -1,3 +1,4 @@ +import { RUNNER_TARGET_VERSION } from '@mimicprotocol/lib-ts/constants' import { Command, Flags } from '@oclif/core' import * as fs from 'fs' import * as path from 'path' @@ -67,6 +68,15 @@ export default class Compile extends Command { }) } + log.startAction('Injecting metadata') + const wasmPath = path.join(absBuildDir, 'function.wasm') + const wasmBuffer = fs.readFileSync(wasmPath) + const metadata = { + runnerTarget: RUNNER_TARGET_VERSION, + } + const wasmWithMetadata = addCustomSection(wasmBuffer, 'mimic-metadata', JSON.stringify(metadata)) + fs.writeFileSync(wasmPath, wasmWithMetadata) + log.startAction('Saving files') fs.writeFileSync(path.join(absBuildDir, 'manifest.json'), JSON.stringify(manifest, null, 2)) @@ -74,3 +84,55 @@ export default class Compile extends Command { console.log(`Build complete! Artifacts in ${absBuildDir}/`) } } + +/** + * Add a custom section to a WASM binary + * @param wasmBuffer - The original WASM binary + * @param sectionName - Name of the custom section + * @param data - String data to store in the section + * @returns Modified WASM binary with the custom section + */ +function addCustomSection(wasmBuffer: Buffer, sectionName: string, data: string): Buffer { + const dataBuffer = Buffer.from(data, 'utf-8') + const nameBuffer = Buffer.from(sectionName, 'utf-8') + + // WASM custom section format: + // - Section ID: 0 (custom section) + // - Section size (LEB128) - size of name length + name + data + // - Name length (LEB128) + // - Name bytes + // - Data bytes + + const nameLengthBuffer = encodeLEB128(nameBuffer.length) + const sectionContentSize = nameLengthBuffer.length + nameBuffer.length + dataBuffer.length + const sectionSizeBuffer = encodeLEB128(sectionContentSize) + + const customSection = Buffer.concat([ + Buffer.from([0]), // Custom section ID + sectionSizeBuffer, + nameLengthBuffer, + nameBuffer, + dataBuffer, + ]) + + // Insert after the WASM header (8 bytes: magic + version) + const headerSize = 8 + return Buffer.concat([wasmBuffer.slice(0, headerSize), customSection, wasmBuffer.slice(headerSize)]) +} + +/** + * Encode an unsigned integer as LEB128 (Little Endian Base 128) + */ +function encodeLEB128(value: number): Buffer { + const bytes: number[] = [] + while (true) { + let byte = value & 0x7f + value >>>= 7 + if (value !== 0) { + byte |= 0x80 + } + bytes.push(byte) + if (value === 0) break + } + return Buffer.from(bytes) +} diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index 8ebf4d93..297d7308 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -1,7 +1,7 @@ +import { RUNNER_TARGET_VERSION } from '@mimicprotocol/lib-ts/constants' import { Command } from '@oclif/core' import * as fs from 'fs' import { load } from 'js-yaml' -import * as path from 'path' import { ZodError } from 'zod' import { DuplicateEntryError, EmptyManifestError, MoreThanOneEntryError } from '../errors' @@ -17,7 +17,7 @@ export default { ...manifest, inputs: mergeIfUnique(manifest.inputs), abis: mergeIfUnique(manifest.abis), - metadata: { libVersion: getLibVersion() }, + metadata: { runnerTarget: RUNNER_TARGET_VERSION }, } return ManifestValidator.parse(mergedManifest) }, @@ -79,18 +79,3 @@ function handleValidationError(command: Command, err: unknown): never { command.error(message, { code, suggestions }) } - -function getLibVersion(): string { - try { - let currentDir = process.cwd() - while (currentDir !== path.dirname(currentDir)) { - const libPackagePath = path.join(currentDir, 'node_modules', '@mimicprotocol', 'lib-ts', 'package.json') - if (fs.existsSync(libPackagePath)) return JSON.parse(fs.readFileSync(libPackagePath, 'utf-8')).version - currentDir = path.dirname(currentDir) - } - - throw new Error('Could not find @mimicprotocol/lib-ts package') - } catch (error) { - throw new Error(`Failed to read @mimicprotocol/lib-ts version: ${error}`) - } -} diff --git a/packages/cli/src/validators.ts b/packages/cli/src/validators.ts index bcf24259..eed2ccfd 100644 --- a/packages/cli/src/validators.ts +++ b/packages/cli/src/validators.ts @@ -22,6 +22,6 @@ export const ManifestValidator = z.object({ inputs: z.record(String, InputValue), abis: z.record(String, String), metadata: z.object({ - libVersion: String.regex(SEM_VER_REGEX, 'Must be a valid semver'), + runnerTarget: String.regex(SEM_VER_REGEX, 'Must be a valid semver'), }), }) diff --git a/packages/lib-ts/constants.ts b/packages/lib-ts/constants.ts new file mode 100644 index 00000000..599d1676 --- /dev/null +++ b/packages/lib-ts/constants.ts @@ -0,0 +1,4 @@ +/** + * Runner target version constant + */ +export const RUNNER_TARGET_VERSION = '0.0.1' diff --git a/packages/lib-ts/package.json b/packages/lib-ts/package.json index bbf78b8e..634438ba 100644 --- a/packages/lib-ts/package.json +++ b/packages/lib-ts/package.json @@ -12,8 +12,13 @@ "files": [ "src", "index.ts", + "constants.ts", "asconfig.json" ], + "exports": { + ".": "./index.ts", + "./constants": "./constants.ts" + }, "devDependencies": { "@as-pect/cli": "8.1.0", "assemblyscript": "0.27.36" From b793e0b3be9855b907c70cddd17cfba114c77208 Mon Sep 17 00:00:00 2001 From: Agustincito Date: Thu, 12 Feb 2026 17:11:11 -0300 Subject: [PATCH 2/3] Add changeset --- .changeset/sunny-chairs-hope.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/sunny-chairs-hope.md diff --git a/.changeset/sunny-chairs-hope.md b/.changeset/sunny-chairs-hope.md new file mode 100644 index 00000000..5f00a2c2 --- /dev/null +++ b/.changeset/sunny-chairs-hope.md @@ -0,0 +1,7 @@ +--- +"@mimicprotocol/lib-ts": patch +"@mimicprotocol/cli": patch +"@mimicprotocol/test-ts": patch +--- + +Add runner target on compilation From beaa5cfed355d3c9345452e800d9593e8e9fc39a Mon Sep 17 00:00:00 2001 From: Agustincito Date: Fri, 13 Feb 2026 14:37:37 -0300 Subject: [PATCH 3/3] Fix comments and tests --- packages/cli/src/commands/compile.ts | 4 ++-- packages/cli/tests/ManifestHandler.spec.ts | 8 ++++---- packages/lib-ts/constants.ts | 3 --- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/commands/compile.ts b/packages/cli/src/commands/compile.ts index 05aa4be1..26f36e84 100644 --- a/packages/cli/src/commands/compile.ts +++ b/packages/cli/src/commands/compile.ts @@ -47,13 +47,14 @@ export default class Compile extends Command { log.startAction('Verifying Manifest') const manifest = ManifestHandler.load(cmd, manifestDir) log.startAction('Compiling') + const wasmPath = path.join(absBuildDir, 'function.wasm') const ascArgs = [ absFunctionFile, '--target', 'release', '--outFile', - path.join(absBuildDir, 'function.wasm'), + wasmPath, '--optimize', '--exportRuntime', '--transform', @@ -69,7 +70,6 @@ export default class Compile extends Command { } log.startAction('Injecting metadata') - const wasmPath = path.join(absBuildDir, 'function.wasm') const wasmBuffer = fs.readFileSync(wasmPath) const metadata = { runnerTarget: RUNNER_TARGET_VERSION, diff --git a/packages/cli/tests/ManifestHandler.spec.ts b/packages/cli/tests/ManifestHandler.spec.ts index 03a62bdf..28fdd6da 100644 --- a/packages/cli/tests/ManifestHandler.spec.ts +++ b/packages/cli/tests/ManifestHandler.spec.ts @@ -71,12 +71,12 @@ describe('ManifestHandler', () => { }) }) - context('when dealing with lib version', () => { - context('when the lib version is not present', () => { - it('adds the lib version to the manifest', () => { + context('when dealing with runner target version', () => { + context('when the runner target version is not present', () => { + it('adds the runner target version to the manifest', () => { const parsedManifest = ManifestHandler.validate(manifest) - expect(parsedManifest.metadata.libVersion).to.match(SEM_VER_REGEX) + expect(parsedManifest.metadata.runnerTarget).to.match(SEM_VER_REGEX) }) }) diff --git a/packages/lib-ts/constants.ts b/packages/lib-ts/constants.ts index 599d1676..8fbdd531 100644 --- a/packages/lib-ts/constants.ts +++ b/packages/lib-ts/constants.ts @@ -1,4 +1 @@ -/** - * Runner target version constant - */ export const RUNNER_TARGET_VERSION = '0.0.1'