@layerzerolabs/vm-tooling-stellar 0.2.126 → 0.2.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { __name } from './VUOMXK5T.js';
2
2
  import { execFile, spawn } from 'child_process';
3
- import { stat } from 'fs/promises';
3
+ import { stat, chmod } from 'fs/promises';
4
4
  import path from 'path';
5
5
  import { promisify } from 'util';
6
6
 
@@ -124,6 +124,9 @@ var VerifiableBuildWrapper = class {
124
124
  cause
125
125
  });
126
126
  }
127
+ if (sourceDir !== void 0) {
128
+ await chmod(buildDir, 511);
129
+ }
127
130
  const tagRef = officialImageTagRef(stellarVersion, rustVersion);
128
131
  const digest = await resolveAmd64Digest(tagRef);
129
132
  const imageRef = `${OFFICIAL_IMAGE_REPO}@${digest}`;
@@ -144,5 +147,5 @@ var VerifiableBuildWrapper = class {
144
147
  };
145
148
 
146
149
  export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, canonicalizeMetaArgs, officialImageTagRef, parseAmd64Digest, resolveBuildDir };
147
- //# sourceMappingURL=EP3GEVT6.js.map
148
- //# sourceMappingURL=EP3GEVT6.js.map
150
+ //# sourceMappingURL=WMMRXU3O.js.map
151
+ //# sourceMappingURL=WMMRXU3O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/verifiable-build.ts"],"names":["execFileAsync","promisify","execFile","SOURCE_MOUNT","VERIFIABLE_BUILD_PLATFORM","OFFICIAL_IMAGE_REPO","officialImageTagRef","stellarVersion","rustVersion","parseAmd64Digest","manifestInspectJson","manifests","JSON","parse","Array","isArray","Error","digest","find","platform","os","architecture","startsWith","resolveAmd64Digest","imageTagRef","stdout","maxBuffer","timeout","cause","META_FLAG","metaKey","entry","eq","indexOf","slice","canonicalizeMetaArgs","buildArgs","injectedMeta","reservedKeys","Set","map","metas","passthrough","addCallerMeta","value","has","push","i","length","arg","undefined","sort","flatMap","meta","buildVerifiableBuildDockerArgs","imageRef","sourceDir","bldimg","resolveBuildDir","cwd","path","resolve","runDocker","dockerArgs","Promise","reject","child","spawn","stdio","on","error","code","signal","VerifiableBuildWrapper","run","args","options","buildDir","stat","isDirectory","chmod","tagRef","console","info","join"],"mappings":"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","file":"WMMRXU3O.js","sourcesContent":["import { execFile, spawn } from 'node:child_process';\nimport { chmod, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport type { ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';\n\nconst execFileAsync = promisify(execFile);\n\n// The self-contained source is mounted here and built in place. The official image's WORKDIR is\n// already /source; we set it explicitly for clarity.\nconst SOURCE_MOUNT = '/source';\n\n// Canonical reproducible platform. External verifiers reproduce the amd64 artifact, so we always\n// run the amd64 image regardless of the host arch (the daemon emulates it when needed).\nconst VERIFIABLE_BUILD_PLATFORM = 'linux/amd64';\n\nconst OFFICIAL_IMAGE_REPO = 'stellar/stellar-cli';\n\n/**\n * The official reproducible image reference for a (Stellar CLI, Rust) version pair, e.g.\n * `stellar/stellar-cli:25.1.0-rust1.90.0-slim-bookworm`. The caller pins both versions; this is the\n * only image the tool builds against.\n */\nexport const officialImageTagRef = (stellarVersion: string, rustVersion: string): string =>\n `${OFFICIAL_IMAGE_REPO}:${stellarVersion}-rust${rustVersion}-slim-bookworm`;\n\n/**\n * Pick the linux/amd64 manifest digest out of `docker manifest inspect` output. Pure/synchronous so\n * the selection (skip the arm64 and the unknown/unknown attestation entries) is unit-testable.\n */\n// The subset of `docker manifest inspect` output (an OCI image index) that we read.\ninterface ManifestDescriptor {\n digest?: string;\n platform?: { os?: string; architecture?: string };\n}\ninterface ManifestIndex {\n manifests?: ManifestDescriptor[];\n}\n\nexport const parseAmd64Digest = (manifestInspectJson: string): string => {\n const { manifests } = JSON.parse(manifestInspectJson) as ManifestIndex;\n\n if (!Array.isArray(manifests)) {\n throw new Error(\n '`docker manifest inspect` did not return a multi-arch index (no `manifests` array)',\n );\n }\n\n const digest = manifests.find(\n ({ platform }) => platform?.os === 'linux' && platform?.architecture === 'amd64',\n )?.digest;\n\n if (typeof digest !== 'string' || !digest.startsWith('sha256:')) {\n throw new Error('No linux/amd64 manifest digest found in `docker manifest inspect` output');\n }\n\n return digest;\n};\n\n/**\n * Resolve the immutable linux/amd64 digest of a `stellar/stellar-cli` tag via a daemon-less\n * registry query (`docker manifest inspect`). This is the reproducible reference an external\n * verifier pins to (SEP-58).\n */\nconst resolveAmd64Digest = async (imageTagRef: string): Promise<string> => {\n try {\n const { stdout } = await execFileAsync('docker', ['manifest', 'inspect', imageTagRef], {\n maxBuffer: 16 * 1024 * 1024,\n timeout: 30_000,\n });\n return parseAmd64Digest(stdout);\n } catch (cause) {\n throw new Error(\n `Failed to resolve the linux/amd64 digest of ${imageTagRef} (\\`docker manifest inspect\\`)`,\n { cause },\n );\n }\n};\n\nconst META_FLAG = '--meta';\n\n/** The `key` of a `key=value` meta entry (the whole string when there is no `=`). */\nconst metaKey = (entry: string): string => {\n const eq = entry.indexOf('=');\n return eq === -1 ? entry : entry.slice(0, eq);\n};\n\n/**\n * Canonicalize `stellar contract build` args so the embedded metadata order is stable.\n *\n * Soroban stores contract metadata as an ORDERED sequence, so the order of `--meta key=value`\n * flags changes the WASM bytes (verified: swapping two `--meta` flags yields a different WASM\n * hash). To keep the build reproducible regardless of the order the caller passed `--meta`, every\n * meta entry — the caller's plus the tool-injected ones — is pulled out, merged, and re-emitted in\n * sorted order. Non-meta args keep their original relative order and precede the sorted metas.\n *\n * Injected keys (e.g. `bldimg`) are tool-controlled and RESERVED: any caller `--meta` reusing an\n * injected key is dropped, so a caller can never override the recorded build image by key\n * collision (before sorting, the injected entry was always appended last and won on its own).\n *\n * Both `--meta k=v` and `--meta=k=v` forms are recognized; a dangling `--meta` with no value (or\n * one followed by another flag) is dropped.\n */\nexport const canonicalizeMetaArgs = (buildArgs: string[], injectedMeta: string[]): string[] => {\n const reservedKeys = new Set(injectedMeta.map(metaKey));\n const metas = [...injectedMeta];\n const passthrough: string[] = [];\n\n // Keep a caller meta unless it collides with a reserved (injected) key.\n const addCallerMeta = (value: string): void => {\n if (!reservedKeys.has(metaKey(value))) metas.push(value);\n };\n\n for (let i = 0; i < buildArgs.length; i++) {\n const arg = buildArgs[i];\n if (arg === undefined) continue;\n if (arg === META_FLAG) {\n const value = buildArgs[i + 1];\n // A meta value is `key=value`; anything starting with `--` is the next flag, so treat\n // this `--meta` as dangling and drop it.\n if (value !== undefined && !value.startsWith('--')) {\n addCallerMeta(value);\n i += 1;\n }\n } else if (arg.startsWith(`${META_FLAG}=`)) {\n addCallerMeta(arg.slice(META_FLAG.length + 1));\n } else {\n passthrough.push(arg);\n }\n }\n\n metas.sort();\n return [...passthrough, ...metas.flatMap((meta) => [META_FLAG, meta])];\n};\n\n/**\n * Assemble the `docker run` argv for a verifiable build. Kept pure and synchronous so the mount /\n * workdir layout and the tool-injected `--meta bldimg=…` are unit-testable without Docker.\n *\n * The official image's ENTRYPOINT is `stellar`, so the trailing `contract build …` runs under it.\n * The source directory is assumed self-contained, so it is mounted at /source and built in place —\n * no surrounding workspace is required. All `--meta` flags (the caller's plus the injected\n * `bldimg`) are sorted into a canonical order so the WASM hash is independent of `--meta` ordering.\n */\nexport const buildVerifiableBuildDockerArgs = ({\n imageRef,\n sourceDir,\n buildArgs,\n bldimg,\n}: {\n imageRef: string;\n sourceDir: string;\n buildArgs: string[];\n bldimg: string;\n}): string[] => [\n 'run',\n '--rm',\n '--platform',\n VERIFIABLE_BUILD_PLATFORM,\n '-v',\n `${sourceDir}:${SOURCE_MOUNT}`,\n '-w',\n SOURCE_MOUNT,\n imageRef,\n 'contract',\n 'build',\n // `bldimg` is injected by us (not the caller): the exact build image, so the WASM records what\n // produced it. It joins the caller's --meta flags in the canonical sorted order.\n ...canonicalizeMetaArgs(buildArgs, [`bldimg=${bldimg}`]),\n];\n\n/**\n * Resolve the directory to build. An explicit `sourceDir` that is relative resolves against the\n * cwd; an absolute one is used as-is; omitting it falls back to the cwd. Kept pure/synchronous so\n * the cwd-vs-explicit-folder precedence is unit-testable without Docker.\n *\n * This is what lets the pipeline decompress a packaged source archive into a scratch directory and\n * build that, instead of always building the process cwd.\n */\nexport const resolveBuildDir = (cwd: string, sourceDir?: string): string =>\n path.resolve(cwd, sourceDir ?? '.');\n\nconst runDocker = (dockerArgs: string[]): Promise<void> =>\n new Promise((resolve, reject) => {\n const child = spawn('docker', dockerArgs, { stdio: 'inherit' });\n child.on('error', (error) =>\n reject(new Error('Failed to spawn docker for the verifiable build', { cause: error })),\n );\n child.on('close', (code, signal) => {\n if (code === 0) {\n resolve();\n } else {\n reject(\n new Error(\n `Verifiable build failed: docker exited with ${\n signal ? `signal ${signal}` : `code ${code}`\n }`,\n ),\n );\n }\n });\n });\n\nexport interface VerifiableBuildVersions {\n stellarVersion: string;\n rustVersion: string;\n}\n\n/**\n * Reproducible `stellar contract build` that runs inside the OFFICIAL `stellar/stellar-cli` image —\n * the exact package an external verifier uses — instead of our own dev image (whose sccache/mold\n * layers could change the WASM).\n *\n * The build runs the official image directly from the HOST: our TypeScript CLI already executes on\n * the host runner, so it can `docker run` the official image itself. This is what an external\n * verifier's plain `docker run` does, and it means we never bind-mount the host Docker socket into\n * a container — eliminating the container-escape / secret-leak surface that mounting the socket\n * would create.\n *\n * The image is `stellar/stellar-cli:<stellarVersion>-rust<rustVersion>-slim-bookworm`, pinned by the\n * caller. For a stable reference we resolve it to its linux/amd64 digest and both RUN that digest\n * and embed it as the `bldimg` WASM metadata (`docker.io/stellar/stellar-cli@sha256:…`) — the tool\n * does this automatically so callers never hand-inject `--meta bldimg=…`. The source directory (the\n * cwd, assumed self-contained) is mounted at /source and built in place, and the official image runs\n * as its own user/toolchain.\n */\nexport class VerifiableBuildWrapper {\n public async run(\n args: string[],\n { stellarVersion, rustVersion }: VerifiableBuildVersions,\n options: ToolCommandExecutionOptions,\n sourceDir?: string,\n ): Promise<void> {\n const buildDir = resolveBuildDir(options.cwd, sourceDir);\n try {\n if (!(await stat(buildDir)).isDirectory()) {\n throw new Error('not a directory');\n }\n } catch (cause) {\n throw new Error(\n `Verifiable build source directory is not an existing directory: ${buildDir}`,\n { cause },\n );\n }\n\n // The official stellar-cli image runs as a non-host UID and must create cargo target\n // dirs under the bind-mounted source. Do not pass --user (that would diverge from what\n // external verifiers run). Only chmod when --source-dir is explicit (typically a\n // throwaway extract dir); never world-write the process cwd.\n if (sourceDir !== undefined) {\n await chmod(buildDir, 0o777);\n }\n\n const tagRef = officialImageTagRef(stellarVersion, rustVersion);\n const digest = await resolveAmd64Digest(tagRef);\n const imageRef = `${OFFICIAL_IMAGE_REPO}@${digest}`;\n const bldimg = `docker.io/${OFFICIAL_IMAGE_REPO}@${digest}`;\n\n const dockerArgs = buildVerifiableBuildDockerArgs({\n imageRef,\n sourceDir: buildDir,\n buildArgs: args,\n bldimg,\n });\n\n console.info('🔒 Verifiable build (official stellar/stellar-cli image, run from host)');\n console.info(` source: ${buildDir}`);\n console.info(` image: ${imageRef} (${VERIFIABLE_BUILD_PLATFORM}, from tag ${tagRef})`);\n console.info(` bldimg: ${bldimg}`);\n console.info(` docker ${dockerArgs.join(' ')}`);\n\n await runDocker(dockerArgs);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"verifiable-build.d.ts","sourceRoot":"","sources":["../../src/commands/verifiable-build.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAc7E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,gBAAgB,MAAM,EAAE,aAAa,MAAM,KAAG,MACH,CAAC;AAehF,eAAO,MAAM,gBAAgB,GAAI,qBAAqB,MAAM,KAAG,MAkB9D,CAAC;AA8BF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,WAAW,MAAM,EAAE,EAAE,cAAc,MAAM,EAAE,KAAG,MAAM,EA8BxF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,GAAI,6CAK5C;IACC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAClB,KAAG,MAAM,EAeT,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,EAAE,YAAY,MAAM,KAAG,MAC3B,CAAC;AAuBxC,MAAM,WAAW,uBAAuB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAsB;IAClB,GAAG,CACZ,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,cAAc,EAAE,WAAW,EAAE,EAAE,uBAAuB,EACxD,OAAO,EAAE,2BAA2B,EACpC,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;CAiCnB"}
1
+ {"version":3,"file":"verifiable-build.d.ts","sourceRoot":"","sources":["../../src/commands/verifiable-build.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAc7E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,gBAAgB,MAAM,EAAE,aAAa,MAAM,KAAG,MACH,CAAC;AAehF,eAAO,MAAM,gBAAgB,GAAI,qBAAqB,MAAM,KAAG,MAkB9D,CAAC;AA8BF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,WAAW,MAAM,EAAE,EAAE,cAAc,MAAM,EAAE,KAAG,MAAM,EA8BxF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,GAAI,6CAK5C;IACC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAClB,KAAG,MAAM,EAeT,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,EAAE,YAAY,MAAM,KAAG,MAC3B,CAAC;AAuBxC,MAAM,WAAW,uBAAuB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAsB;IAClB,GAAG,CACZ,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,cAAc,EAAE,WAAW,EAAE,EAAE,uBAAuB,EACxD,OAAO,EAAE,2BAA2B,EACpC,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;CAyCnB"}
@@ -1,4 +1,4 @@
1
- export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, canonicalizeMetaArgs, officialImageTagRef, parseAmd64Digest, resolveBuildDir } from '../EP3GEVT6.js';
1
+ export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, canonicalizeMetaArgs, officialImageTagRef, parseAmd64Digest, resolveBuildDir } from '../WMMRXU3O.js';
2
2
  import '../VUOMXK5T.js';
3
3
  //# sourceMappingURL=verifiable-build.js.map
4
4
  //# sourceMappingURL=verifiable-build.js.map
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { packageSource } from './LCHYL2IQ.js';
2
- import { VerifiableBuildWrapper } from './EP3GEVT6.js';
2
+ import { VerifiableBuildWrapper } from './WMMRXU3O.js';
3
3
  import { versionCombinations, images, tools } from './AY7HGKNR.js';
4
4
  import { syncToolchain } from './P6KJGYNA.js';
5
5
  import { __name } from './VUOMXK5T.js';
package/package.json CHANGED
@@ -20,8 +20,8 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "toml": "^3.0.0",
23
- "@layerzerolabs/deterministic-zip": "0.2.126",
24
- "@layerzerolabs/vm-tooling": "0.2.126"
23
+ "@layerzerolabs/deterministic-zip": "0.2.127",
24
+ "@layerzerolabs/vm-tooling": "0.2.127"
25
25
  },
26
26
  "devDependencies": {
27
27
  "fflate": "^0.8.3",
@@ -29,9 +29,9 @@
29
29
  "tsx": "^4.21.0",
30
30
  "typescript": "^5.8.2",
31
31
  "vitest": "^3.2.6",
32
- "@layerzerolabs/tsup-configuration": "0.2.126",
33
- "@layerzerolabs/typescript-configuration": "0.2.126",
34
- "@layerzerolabs/vitest-configuration": "0.2.126"
32
+ "@layerzerolabs/vitest-configuration": "0.2.127",
33
+ "@layerzerolabs/typescript-configuration": "0.2.127",
34
+ "@layerzerolabs/tsup-configuration": "0.2.127"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public",
@@ -45,7 +45,7 @@
45
45
  "onesig-client"
46
46
  ]
47
47
  },
48
- "version": "0.2.126",
48
+ "version": "0.2.127",
49
49
  "scripts": {
50
50
  "build": "tsup",
51
51
  "generate-github-matrix": "tsx src/scripts/generate-github-matrix.ts",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/verifiable-build.ts"],"names":["execFileAsync","promisify","execFile","SOURCE_MOUNT","VERIFIABLE_BUILD_PLATFORM","OFFICIAL_IMAGE_REPO","officialImageTagRef","stellarVersion","rustVersion","parseAmd64Digest","manifestInspectJson","manifests","JSON","parse","Array","isArray","Error","digest","find","platform","os","architecture","startsWith","resolveAmd64Digest","imageTagRef","stdout","maxBuffer","timeout","cause","META_FLAG","metaKey","entry","eq","indexOf","slice","canonicalizeMetaArgs","buildArgs","injectedMeta","reservedKeys","Set","map","metas","passthrough","addCallerMeta","value","has","push","i","length","arg","undefined","sort","flatMap","meta","buildVerifiableBuildDockerArgs","imageRef","sourceDir","bldimg","resolveBuildDir","cwd","path","resolve","runDocker","dockerArgs","Promise","reject","child","spawn","stdio","on","error","code","signal","VerifiableBuildWrapper","run","args","options","buildDir","stat","isDirectory","tagRef","console","info","join"],"mappings":"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","file":"EP3GEVT6.js","sourcesContent":["import { execFile, spawn } from 'node:child_process';\nimport { stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport type { ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';\n\nconst execFileAsync = promisify(execFile);\n\n// The self-contained source is mounted here and built in place. The official image's WORKDIR is\n// already /source; we set it explicitly for clarity.\nconst SOURCE_MOUNT = '/source';\n\n// Canonical reproducible platform. External verifiers reproduce the amd64 artifact, so we always\n// run the amd64 image regardless of the host arch (the daemon emulates it when needed).\nconst VERIFIABLE_BUILD_PLATFORM = 'linux/amd64';\n\nconst OFFICIAL_IMAGE_REPO = 'stellar/stellar-cli';\n\n/**\n * The official reproducible image reference for a (Stellar CLI, Rust) version pair, e.g.\n * `stellar/stellar-cli:25.1.0-rust1.90.0-slim-bookworm`. The caller pins both versions; this is the\n * only image the tool builds against.\n */\nexport const officialImageTagRef = (stellarVersion: string, rustVersion: string): string =>\n `${OFFICIAL_IMAGE_REPO}:${stellarVersion}-rust${rustVersion}-slim-bookworm`;\n\n/**\n * Pick the linux/amd64 manifest digest out of `docker manifest inspect` output. Pure/synchronous so\n * the selection (skip the arm64 and the unknown/unknown attestation entries) is unit-testable.\n */\n// The subset of `docker manifest inspect` output (an OCI image index) that we read.\ninterface ManifestDescriptor {\n digest?: string;\n platform?: { os?: string; architecture?: string };\n}\ninterface ManifestIndex {\n manifests?: ManifestDescriptor[];\n}\n\nexport const parseAmd64Digest = (manifestInspectJson: string): string => {\n const { manifests } = JSON.parse(manifestInspectJson) as ManifestIndex;\n\n if (!Array.isArray(manifests)) {\n throw new Error(\n '`docker manifest inspect` did not return a multi-arch index (no `manifests` array)',\n );\n }\n\n const digest = manifests.find(\n ({ platform }) => platform?.os === 'linux' && platform?.architecture === 'amd64',\n )?.digest;\n\n if (typeof digest !== 'string' || !digest.startsWith('sha256:')) {\n throw new Error('No linux/amd64 manifest digest found in `docker manifest inspect` output');\n }\n\n return digest;\n};\n\n/**\n * Resolve the immutable linux/amd64 digest of a `stellar/stellar-cli` tag via a daemon-less\n * registry query (`docker manifest inspect`). This is the reproducible reference an external\n * verifier pins to (SEP-58).\n */\nconst resolveAmd64Digest = async (imageTagRef: string): Promise<string> => {\n try {\n const { stdout } = await execFileAsync('docker', ['manifest', 'inspect', imageTagRef], {\n maxBuffer: 16 * 1024 * 1024,\n timeout: 30_000,\n });\n return parseAmd64Digest(stdout);\n } catch (cause) {\n throw new Error(\n `Failed to resolve the linux/amd64 digest of ${imageTagRef} (\\`docker manifest inspect\\`)`,\n { cause },\n );\n }\n};\n\nconst META_FLAG = '--meta';\n\n/** The `key` of a `key=value` meta entry (the whole string when there is no `=`). */\nconst metaKey = (entry: string): string => {\n const eq = entry.indexOf('=');\n return eq === -1 ? entry : entry.slice(0, eq);\n};\n\n/**\n * Canonicalize `stellar contract build` args so the embedded metadata order is stable.\n *\n * Soroban stores contract metadata as an ORDERED sequence, so the order of `--meta key=value`\n * flags changes the WASM bytes (verified: swapping two `--meta` flags yields a different WASM\n * hash). To keep the build reproducible regardless of the order the caller passed `--meta`, every\n * meta entry — the caller's plus the tool-injected ones — is pulled out, merged, and re-emitted in\n * sorted order. Non-meta args keep their original relative order and precede the sorted metas.\n *\n * Injected keys (e.g. `bldimg`) are tool-controlled and RESERVED: any caller `--meta` reusing an\n * injected key is dropped, so a caller can never override the recorded build image by key\n * collision (before sorting, the injected entry was always appended last and won on its own).\n *\n * Both `--meta k=v` and `--meta=k=v` forms are recognized; a dangling `--meta` with no value (or\n * one followed by another flag) is dropped.\n */\nexport const canonicalizeMetaArgs = (buildArgs: string[], injectedMeta: string[]): string[] => {\n const reservedKeys = new Set(injectedMeta.map(metaKey));\n const metas = [...injectedMeta];\n const passthrough: string[] = [];\n\n // Keep a caller meta unless it collides with a reserved (injected) key.\n const addCallerMeta = (value: string): void => {\n if (!reservedKeys.has(metaKey(value))) metas.push(value);\n };\n\n for (let i = 0; i < buildArgs.length; i++) {\n const arg = buildArgs[i];\n if (arg === undefined) continue;\n if (arg === META_FLAG) {\n const value = buildArgs[i + 1];\n // A meta value is `key=value`; anything starting with `--` is the next flag, so treat\n // this `--meta` as dangling and drop it.\n if (value !== undefined && !value.startsWith('--')) {\n addCallerMeta(value);\n i += 1;\n }\n } else if (arg.startsWith(`${META_FLAG}=`)) {\n addCallerMeta(arg.slice(META_FLAG.length + 1));\n } else {\n passthrough.push(arg);\n }\n }\n\n metas.sort();\n return [...passthrough, ...metas.flatMap((meta) => [META_FLAG, meta])];\n};\n\n/**\n * Assemble the `docker run` argv for a verifiable build. Kept pure and synchronous so the mount /\n * workdir layout and the tool-injected `--meta bldimg=…` are unit-testable without Docker.\n *\n * The official image's ENTRYPOINT is `stellar`, so the trailing `contract build …` runs under it.\n * The source directory is assumed self-contained, so it is mounted at /source and built in place —\n * no surrounding workspace is required. All `--meta` flags (the caller's plus the injected\n * `bldimg`) are sorted into a canonical order so the WASM hash is independent of `--meta` ordering.\n */\nexport const buildVerifiableBuildDockerArgs = ({\n imageRef,\n sourceDir,\n buildArgs,\n bldimg,\n}: {\n imageRef: string;\n sourceDir: string;\n buildArgs: string[];\n bldimg: string;\n}): string[] => [\n 'run',\n '--rm',\n '--platform',\n VERIFIABLE_BUILD_PLATFORM,\n '-v',\n `${sourceDir}:${SOURCE_MOUNT}`,\n '-w',\n SOURCE_MOUNT,\n imageRef,\n 'contract',\n 'build',\n // `bldimg` is injected by us (not the caller): the exact build image, so the WASM records what\n // produced it. It joins the caller's --meta flags in the canonical sorted order.\n ...canonicalizeMetaArgs(buildArgs, [`bldimg=${bldimg}`]),\n];\n\n/**\n * Resolve the directory to build. An explicit `sourceDir` that is relative resolves against the\n * cwd; an absolute one is used as-is; omitting it falls back to the cwd. Kept pure/synchronous so\n * the cwd-vs-explicit-folder precedence is unit-testable without Docker.\n *\n * This is what lets the pipeline decompress a packaged source archive into a scratch directory and\n * build that, instead of always building the process cwd.\n */\nexport const resolveBuildDir = (cwd: string, sourceDir?: string): string =>\n path.resolve(cwd, sourceDir ?? '.');\n\nconst runDocker = (dockerArgs: string[]): Promise<void> =>\n new Promise((resolve, reject) => {\n const child = spawn('docker', dockerArgs, { stdio: 'inherit' });\n child.on('error', (error) =>\n reject(new Error('Failed to spawn docker for the verifiable build', { cause: error })),\n );\n child.on('close', (code, signal) => {\n if (code === 0) {\n resolve();\n } else {\n reject(\n new Error(\n `Verifiable build failed: docker exited with ${\n signal ? `signal ${signal}` : `code ${code}`\n }`,\n ),\n );\n }\n });\n });\n\nexport interface VerifiableBuildVersions {\n stellarVersion: string;\n rustVersion: string;\n}\n\n/**\n * Reproducible `stellar contract build` that runs inside the OFFICIAL `stellar/stellar-cli` image —\n * the exact package an external verifier uses — instead of our own dev image (whose sccache/mold\n * layers could change the WASM).\n *\n * The build runs the official image directly from the HOST: our TypeScript CLI already executes on\n * the host runner, so it can `docker run` the official image itself. This is what an external\n * verifier's plain `docker run` does, and it means we never bind-mount the host Docker socket into\n * a container — eliminating the container-escape / secret-leak surface that mounting the socket\n * would create.\n *\n * The image is `stellar/stellar-cli:<stellarVersion>-rust<rustVersion>-slim-bookworm`, pinned by the\n * caller. For a stable reference we resolve it to its linux/amd64 digest and both RUN that digest\n * and embed it as the `bldimg` WASM metadata (`docker.io/stellar/stellar-cli@sha256:…`) — the tool\n * does this automatically so callers never hand-inject `--meta bldimg=…`. The source directory (the\n * cwd, assumed self-contained) is mounted at /source and built in place, and the official image runs\n * as its own user/toolchain.\n */\nexport class VerifiableBuildWrapper {\n public async run(\n args: string[],\n { stellarVersion, rustVersion }: VerifiableBuildVersions,\n options: ToolCommandExecutionOptions,\n sourceDir?: string,\n ): Promise<void> {\n const buildDir = resolveBuildDir(options.cwd, sourceDir);\n try {\n if (!(await stat(buildDir)).isDirectory()) {\n throw new Error('not a directory');\n }\n } catch (cause) {\n throw new Error(\n `Verifiable build source directory is not an existing directory: ${buildDir}`,\n { cause },\n );\n }\n\n const tagRef = officialImageTagRef(stellarVersion, rustVersion);\n const digest = await resolveAmd64Digest(tagRef);\n const imageRef = `${OFFICIAL_IMAGE_REPO}@${digest}`;\n const bldimg = `docker.io/${OFFICIAL_IMAGE_REPO}@${digest}`;\n\n const dockerArgs = buildVerifiableBuildDockerArgs({\n imageRef,\n sourceDir: buildDir,\n buildArgs: args,\n bldimg,\n });\n\n console.info('🔒 Verifiable build (official stellar/stellar-cli image, run from host)');\n console.info(` source: ${buildDir}`);\n console.info(` image: ${imageRef} (${VERIFIABLE_BUILD_PLATFORM}, from tag ${tagRef})`);\n console.info(` bldimg: ${bldimg}`);\n console.info(` docker ${dockerArgs.join(' ')}`);\n\n await runDocker(dockerArgs);\n }\n}\n"]}