@layerzerolabs/vm-tooling-stellar 0.2.122 → 0.2.124

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.
Files changed (38) hide show
  1. package/dist/{PT2VYI7I.js → AY7HGKNR.js} +3 -6
  2. package/dist/AY7HGKNR.js.map +1 -0
  3. package/dist/{6YPWRWU3.js → EP3GEVT6.js} +65 -13
  4. package/dist/EP3GEVT6.js.map +1 -0
  5. package/dist/LCHYL2IQ.js +115 -0
  6. package/dist/LCHYL2IQ.js.map +1 -0
  7. package/dist/{K7N3LKMZ.js → P6KJGYNA.js} +3 -5
  8. package/dist/P6KJGYNA.js.map +1 -0
  9. package/dist/VUOMXK5T.js +6 -0
  10. package/dist/VUOMXK5T.js.map +1 -0
  11. package/dist/commands/package-source.d.ts +55 -0
  12. package/dist/commands/package-source.d.ts.map +1 -0
  13. package/dist/commands/package-source.js +4 -0
  14. package/dist/commands/package-source.js.map +1 -0
  15. package/dist/commands/sync-toolchain.js +2 -2
  16. package/dist/commands/verifiable-build.d.ts +29 -2
  17. package/dist/commands/verifiable-build.d.ts.map +1 -1
  18. package/dist/commands/verifiable-build.js +2 -2
  19. package/dist/config.js +3 -3
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +11 -7
  22. package/dist/index.js.map +1 -1
  23. package/dist/scripts/generate-github-matrix.js +3 -5
  24. package/dist/scripts/generate-github-matrix.js.map +1 -1
  25. package/package.json +7 -5
  26. package/dist/2VBLSQAK.js +0 -44
  27. package/dist/2VBLSQAK.js.map +0 -1
  28. package/dist/6YPWRWU3.js.map +0 -1
  29. package/dist/ITF544RZ.js +0 -18485
  30. package/dist/ITF544RZ.js.map +0 -1
  31. package/dist/K7N3LKMZ.js.map +0 -1
  32. package/dist/PT2VYI7I.js.map +0 -1
  33. package/dist/RR7PDZXI.js +0 -1341
  34. package/dist/RR7PDZXI.js.map +0 -1
  35. package/dist/commands/verifiable-build.test.js +0 -120
  36. package/dist/commands/verifiable-build.test.js.map +0 -1
  37. package/dist/index.test.js +0 -16
  38. package/dist/index.test.js.map +0 -1
@@ -1,9 +1,6 @@
1
- import { syncToolchain } from './K7N3LKMZ.js';
2
- import { init_esm_shims } from './2VBLSQAK.js';
1
+ import { syncToolchain } from './P6KJGYNA.js';
3
2
  import { DockerRegistryMirror } from '@layerzerolabs/vm-tooling';
4
3
 
5
- // src/config.ts
6
- init_esm_shims();
7
4
  var tools = [
8
5
  {
9
6
  name: "stellar",
@@ -109,5 +106,5 @@ var versionCombinations = [
109
106
  ];
110
107
 
111
108
  export { images, tools, versionCombinations };
112
- //# sourceMappingURL=PT2VYI7I.js.map
113
- //# sourceMappingURL=PT2VYI7I.js.map
109
+ //# sourceMappingURL=AY7HGKNR.js.map
110
+ //# sourceMappingURL=AY7HGKNR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"names":["tools","name","preExecute","syncToolchain","dockerPlatform","defaultVolumes","type","containerPath","shared","hostPath","defaultEnv","value","images","versions","stellar","patch","mirrorRegistries","DockerRegistryMirror","PUBLIC_GAR","dependencies","rust","versionCombinations","description","stable"],"mappings":";;;AASO,IAAMA,KAAAA,GAAoC;AAC7C,EAAA;IACIC,IAAAA,EAAM,SAAA;IACNC,UAAAA,EAAYC,aAAAA;IACZC,cAAAA,EAAgB,aAAA;IAChBC,cAAAA,EAAgB;;;AAGZ,MAAA;QACIC,IAAAA,EAAM,SAAA;QACNC,aAAAA,EAAe,gBAAA;QACfN,IAAAA,EAAM,gBAAA;QACNO,MAAAA,EAAQ;AACZ,OAAA;;AAEA,MAAA;QACIF,IAAAA,EAAM,SAAA;QACNC,aAAAA,EAAe,cAAA;QACfN,IAAAA,EAAM,eAAA;QACNO,MAAAA,EAAQ;AACZ,OAAA;;;AAGA,MAAA;QACIF,IAAAA,EAAM,SAAA;QACNC,aAAAA,EAAe,eAAA;QACfN,IAAAA,EAAM,gBAAA;QACNO,MAAAA,EAAQ;AACZ,OAAA;;AAEA,MAAA;QACIF,IAAAA,EAAM,MAAA;QACNC,aAAAA,EAAe,gBAAA;QACfE,QAAAA,EAAU;AACd;;IAEJC,UAAAA,EAAY;;AAER,MAAA;QAAET,IAAAA,EAAM,eAAA;QAAiBU,KAAAA,EAAO;AAAyB,OAAA;;AAEzD,MAAA;QAAEV,IAAAA,EAAM,8CAAA;QAAgDU,KAAAA,EAAO;AAAQ,OAAA;AACvE,MAAA;QAAEV,IAAAA,EAAM,+CAAA;QAAiDU,KAAAA,EAAO;AAAQ,OAAA;AACxE,MAAA;QACIV,IAAAA,EAAM,iDAAA;QACNU,KAAAA,EAAO;AACX,OAAA;AACA,MAAA;QACIV,IAAAA,EAAM,kDAAA;QACNU,KAAAA,EAAO;AACX;;AAER;;AAGG,IAAMC,MAAAA,GAAS;AAClB,EAAA,CAAC,gCAAA,GAAmC;IAChCX,IAAAA,EAAM,SAAA;IACNY,QAAAA,EAAU;MACNC,OAAAA,EAAS;AACb,KAAA;IACAC,KAAAA,EAAO,CAAA;IACPC,gBAAAA,EAAkB;MAACC,oBAAAA,CAAqBC;;AAC5C,GAAA;AACA,EAAA,CAAC,gCAAA,GAAmC;IAChCjB,IAAAA,EAAM,SAAA;IACNY,QAAAA,EAAU;MACNC,OAAAA,EAAS;AACb,KAAA;IACAC,KAAAA,EAAO,CAAA;IACPI,YAAAA,EAAc;MACVC,IAAAA,EAAM;AACV,KAAA;IACAJ,gBAAAA,EAAkB;MAACC,oBAAAA,CAAqBC;;AAC5C;AACJ;AAIO,IAAMG,mBAAAA,GACT;AACI,EAAA;IACIT,MAAAA,EAAQ;MACJE,OAAAA,EAAS;AACb,KAAA;IACAQ,WAAAA,EAAa,uBAAA;IACbC,MAAAA,EAAQ;AACZ,GAAA;AACA,EAAA;IACIX,MAAAA,EAAQ;MACJE,OAAAA,EAAS;AACb,KAAA;IACAQ,WAAAA,EAAa,gBAAA;IACbC,MAAAA,EAAQ;AACZ","file":"AY7HGKNR.js","sourcesContent":["import {\n DockerRegistryMirror,\n type Image,\n type Tool,\n type VersionCombination,\n} from '@layerzerolabs/vm-tooling';\n\nimport { syncToolchain } from './commands/sync-toolchain';\n\nexport const tools: readonly [Tool, ...Tool[]] = [\n {\n name: 'stellar',\n preExecute: syncToolchain,\n dockerPlatform: 'linux/amd64',\n defaultVolumes: [\n // NOTE: for configuration commands, you should never put it in your package.json#build or #test, since the config is locked for parallel builds\n // while common commands like contract build and binding generation are allowed since they are not writing to the config files\n {\n type: 'isolate',\n containerPath: '/cache/stellar',\n name: 'stellar-config',\n shared: true,\n },\n // safe to be unlocked as it is POSIX lock guarded\n {\n type: 'isolate',\n containerPath: '/cache/cargo',\n name: 'stellar-cargo',\n shared: true,\n },\n // shared across packages — toolchain is pre-synced via `sync-toolchain` (locked)\n // so concurrent reads from build/test/lint are safe\n {\n type: 'isolate',\n containerPath: '/cache/rustup',\n name: 'stellar-rustup',\n shared: true,\n },\n // safe as the wort case of corruption is cache miss, since it is key-based cache, concurrent writes will produce identical content\n {\n type: 'host',\n containerPath: '/cache/sccache',\n hostPath: '~/.sccache',\n },\n ],\n defaultEnv: [\n // sccache configuration\n { name: 'RUSTC_WRAPPER', value: '/usr/local/bin/sccache' },\n // mold linker for faster linking\n { name: 'CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER', value: 'clang' },\n { name: 'CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER', value: 'clang' },\n {\n name: 'CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS',\n value: '-C link-arg=-fuse-ld=mold',\n },\n {\n name: 'CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS',\n value: '-C link-arg=-fuse-ld=mold',\n },\n ],\n },\n];\n\nexport const images = {\n ['stellar:stellar-25.1.0-patch-2']: {\n name: 'stellar',\n versions: {\n stellar: '25.1.0',\n },\n patch: 2,\n mirrorRegistries: [DockerRegistryMirror.PUBLIC_GAR],\n },\n ['stellar:stellar-25.2.0-patch-1']: {\n name: 'stellar',\n versions: {\n stellar: '25.2.0',\n },\n patch: 1,\n dependencies: {\n rust: '1.91.0',\n },\n mirrorRegistries: [DockerRegistryMirror.PUBLIC_GAR],\n },\n} satisfies Record<string, Image>;\n\nexport type ImageId = keyof typeof images;\n\nexport const versionCombinations: [VersionCombination<ImageId>, ...VersionCombination<ImageId>[]] =\n [\n {\n images: {\n stellar: 'stellar:stellar-25.1.0-patch-2',\n },\n description: 'Latest stable release',\n stable: true,\n },\n {\n images: {\n stellar: 'stellar:stellar-25.2.0-patch-1',\n },\n description: 'Stellar 25.2.0',\n stable: true,\n },\n ];\n"]}
@@ -1,9 +1,9 @@
1
- import { init_esm_shims, __name } from './2VBLSQAK.js';
1
+ import { __name } from './VUOMXK5T.js';
2
2
  import { execFile, spawn } from 'child_process';
3
+ import { stat } from 'fs/promises';
4
+ import path from 'path';
3
5
  import { promisify } from 'util';
4
6
 
5
- // src/commands/verifiable-build.ts
6
- init_esm_shims();
7
7
  var execFileAsync = promisify(execFile);
8
8
  var SOURCE_MOUNT = "/source";
9
9
  var VERIFIABLE_BUILD_PLATFORM = "linux/amd64";
@@ -27,7 +27,8 @@ var resolveAmd64Digest = /* @__PURE__ */ __name(async (imageTagRef) => {
27
27
  "inspect",
28
28
  imageTagRef
29
29
  ], {
30
- maxBuffer: 16 * 1024 * 1024
30
+ maxBuffer: 16 * 1024 * 1024,
31
+ timeout: 3e4
31
32
  });
32
33
  return parseAmd64Digest(stdout);
33
34
  } catch (cause) {
@@ -36,6 +37,44 @@ var resolveAmd64Digest = /* @__PURE__ */ __name(async (imageTagRef) => {
36
37
  });
37
38
  }
38
39
  }, "resolveAmd64Digest");
40
+ var META_FLAG = "--meta";
41
+ var metaKey = /* @__PURE__ */ __name((entry) => {
42
+ const eq = entry.indexOf("=");
43
+ return eq === -1 ? entry : entry.slice(0, eq);
44
+ }, "metaKey");
45
+ var canonicalizeMetaArgs = /* @__PURE__ */ __name((buildArgs, injectedMeta) => {
46
+ const reservedKeys = new Set(injectedMeta.map(metaKey));
47
+ const metas = [
48
+ ...injectedMeta
49
+ ];
50
+ const passthrough = [];
51
+ const addCallerMeta = /* @__PURE__ */ __name((value) => {
52
+ if (!reservedKeys.has(metaKey(value))) metas.push(value);
53
+ }, "addCallerMeta");
54
+ for (let i = 0; i < buildArgs.length; i++) {
55
+ const arg = buildArgs[i];
56
+ if (arg === void 0) continue;
57
+ if (arg === META_FLAG) {
58
+ const value = buildArgs[i + 1];
59
+ if (value !== void 0 && !value.startsWith("--")) {
60
+ addCallerMeta(value);
61
+ i += 1;
62
+ }
63
+ } else if (arg.startsWith(`${META_FLAG}=`)) {
64
+ addCallerMeta(arg.slice(META_FLAG.length + 1));
65
+ } else {
66
+ passthrough.push(arg);
67
+ }
68
+ }
69
+ metas.sort();
70
+ return [
71
+ ...passthrough,
72
+ ...metas.flatMap((meta) => [
73
+ META_FLAG,
74
+ meta
75
+ ])
76
+ ];
77
+ }, "canonicalizeMetaArgs");
39
78
  var buildVerifiableBuildDockerArgs = /* @__PURE__ */ __name(({ imageRef, sourceDir, buildArgs, bldimg }) => [
40
79
  "run",
41
80
  "--rm",
@@ -48,11 +87,13 @@ var buildVerifiableBuildDockerArgs = /* @__PURE__ */ __name(({ imageRef, sourceD
48
87
  imageRef,
49
88
  "contract",
50
89
  "build",
51
- ...buildArgs,
52
- // Embedded by us (not the user): the exact build image, so the WASM records what produced it.
53
- "--meta",
54
- `bldimg=${bldimg}`
90
+ // `bldimg` is injected by us (not the caller): the exact build image, so the WASM records what
91
+ // produced it. It joins the caller's --meta flags in the canonical sorted order.
92
+ ...canonicalizeMetaArgs(buildArgs, [
93
+ `bldimg=${bldimg}`
94
+ ])
55
95
  ], "buildVerifiableBuildDockerArgs");
96
+ var resolveBuildDir = /* @__PURE__ */ __name((cwd, sourceDir) => path.resolve(cwd, sourceDir ?? "."), "resolveBuildDir");
56
97
  var runDocker = /* @__PURE__ */ __name((dockerArgs) => new Promise((resolve, reject) => {
57
98
  const child = spawn("docker", dockerArgs, {
58
99
  stdio: "inherit"
@@ -72,18 +113,29 @@ var VerifiableBuildWrapper = class {
72
113
  static {
73
114
  __name(this, "VerifiableBuildWrapper");
74
115
  }
75
- async run(args, { stellarVersion, rustVersion }, options) {
116
+ async run(args, { stellarVersion, rustVersion }, options, sourceDir) {
117
+ const buildDir = resolveBuildDir(options.cwd, sourceDir);
118
+ try {
119
+ if (!(await stat(buildDir)).isDirectory()) {
120
+ throw new Error("not a directory");
121
+ }
122
+ } catch (cause) {
123
+ throw new Error(`Verifiable build source directory is not an existing directory: ${buildDir}`, {
124
+ cause
125
+ });
126
+ }
76
127
  const tagRef = officialImageTagRef(stellarVersion, rustVersion);
77
128
  const digest = await resolveAmd64Digest(tagRef);
78
129
  const imageRef = `${OFFICIAL_IMAGE_REPO}@${digest}`;
79
130
  const bldimg = `docker.io/${OFFICIAL_IMAGE_REPO}@${digest}`;
80
131
  const dockerArgs = buildVerifiableBuildDockerArgs({
81
132
  imageRef,
82
- sourceDir: options.cwd,
133
+ sourceDir: buildDir,
83
134
  buildArgs: args,
84
135
  bldimg
85
136
  });
86
137
  console.info("\u{1F512} Verifiable build (official stellar/stellar-cli image, run from host)");
138
+ console.info(` source: ${buildDir}`);
87
139
  console.info(` image: ${imageRef} (${VERIFIABLE_BUILD_PLATFORM}, from tag ${tagRef})`);
88
140
  console.info(` bldimg: ${bldimg}`);
89
141
  console.info(` docker ${dockerArgs.join(" ")}`);
@@ -91,6 +143,6 @@ var VerifiableBuildWrapper = class {
91
143
  }
92
144
  };
93
145
 
94
- export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, officialImageTagRef, parseAmd64Digest };
95
- //# sourceMappingURL=6YPWRWU3.js.map
96
- //# sourceMappingURL=6YPWRWU3.js.map
146
+ export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, canonicalizeMetaArgs, officialImageTagRef, parseAmd64Digest, resolveBuildDir };
147
+ //# sourceMappingURL=EP3GEVT6.js.map
148
+ //# sourceMappingURL=EP3GEVT6.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","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"]}
@@ -0,0 +1,115 @@
1
+ import { __name } from './VUOMXK5T.js';
2
+ import { createHash } from 'crypto';
3
+ import { access, mkdir, writeFile } from 'fs/promises';
4
+ import path from 'path';
5
+ import { ZipEntryType, zipDirectoryToUint8Array } from '@layerzerolabs/deterministic-zip';
6
+
7
+ var ARTIFACTS_DIR = ".artifacts";
8
+ var NON_SOURCE_DIRS = /* @__PURE__ */ new Set([
9
+ // build / cache output
10
+ "target",
11
+ "docker-target",
12
+ "dist",
13
+ ".turbo",
14
+ // dependency installs — the self-contained copy lives in dependencies/
15
+ "node_modules",
16
+ // vcs / ci
17
+ ".git",
18
+ ".github",
19
+ // local tool config / caches / credentials
20
+ ".cargo",
21
+ ".soroban",
22
+ ".stellar",
23
+ ".aws",
24
+ ".claude",
25
+ // stellar test artifacts
26
+ "test_snapshots",
27
+ // our own output directory
28
+ ARTIFACTS_DIR
29
+ ]);
30
+ var DEFAULT_INCLUDE_GLOBS = [
31
+ "**/*.rs",
32
+ "**/*.lock",
33
+ "**/Cargo.toml",
34
+ "rust-toolchain.toml",
35
+ "rustfmt.toml",
36
+ "clippy.toml"
37
+ ];
38
+ var REQUIRED_ROOT_FILES = [
39
+ "Cargo.toml",
40
+ "Cargo.lock"
41
+ ];
42
+ var makeSourcePredicate = /* @__PURE__ */ __name(({ rootDirName, include = [], exclude = [] }) => {
43
+ const rootPrefix = `${rootDirName}/`;
44
+ const defaultIncludePatterns = DEFAULT_INCLUDE_GLOBS.map((pattern) => `${rootDirName}/${pattern}`);
45
+ const includePatterns = include.map((pattern) => `${rootDirName}/${pattern}`);
46
+ const excludePatterns = exclude.map((pattern) => `${rootDirName}/${pattern}`);
47
+ return ({ relPath, type }) => {
48
+ if (relPath !== rootDirName && !relPath.startsWith(rootPrefix)) {
49
+ return false;
50
+ }
51
+ if (excludePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern))) {
52
+ return false;
53
+ }
54
+ if (type === ZipEntryType.Directory) {
55
+ if (NON_SOURCE_DIRS.has(path.posix.basename(relPath))) return false;
56
+ return true;
57
+ }
58
+ return defaultIncludePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern)) || includePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern));
59
+ };
60
+ }, "makeSourcePredicate");
61
+ var packageSource = /* @__PURE__ */ __name(async ({ output, include = [], exclude = [] }, { cwd }) => {
62
+ const sourceDir = path.resolve(cwd);
63
+ const rootDirName = path.basename(sourceDir);
64
+ const parentDir = path.dirname(sourceDir);
65
+ const outputPath = output ? path.resolve(sourceDir, output) : path.join(sourceDir, ARTIFACTS_DIR, `${rootDirName}-source.zip`);
66
+ for (const name of REQUIRED_ROOT_FILES) {
67
+ try {
68
+ await access(path.join(sourceDir, name));
69
+ } catch {
70
+ throw new Error(`${name} must exist at the crate root to package a reproducible source archive (looked for ${path.join(sourceDir, name)})`);
71
+ }
72
+ }
73
+ const relOutput = path.relative(sourceDir, outputPath);
74
+ const isOutputInsideSource = relOutput !== "" && !relOutput.startsWith("..") && !path.isAbsolute(relOutput);
75
+ const relOutputPosix = relOutput.split(path.sep).join("/");
76
+ const isUnderArtifacts = relOutputPosix.startsWith(`${ARTIFACTS_DIR}/`);
77
+ if (isOutputInsideSource && !isUnderArtifacts) {
78
+ throw new Error(`--output must be under ${ARTIFACTS_DIR}/ or outside the source directory, got "${relOutputPosix}". Any other location inside ${sourceDir} would be captured in the archive and break reproducibility.`);
79
+ }
80
+ let includedFileCount = 0;
81
+ const predicate = makeSourcePredicate({
82
+ rootDirName,
83
+ include,
84
+ exclude
85
+ });
86
+ const countingPredicate = /* @__PURE__ */ __name((entry) => {
87
+ const keep = predicate(entry);
88
+ if (keep && entry.type === ZipEntryType.File) includedFileCount += 1;
89
+ return keep;
90
+ }, "countingPredicate");
91
+ let bytes;
92
+ try {
93
+ bytes = await zipDirectoryToUint8Array(parentDir, {
94
+ pathInclusionPredicate: countingPredicate
95
+ });
96
+ } catch (cause) {
97
+ throw new Error(`Failed to package source: ${sourceDir}`, {
98
+ cause
99
+ });
100
+ }
101
+ if (includedFileCount === 0) {
102
+ throw new Error(`Failed to package source: no source files matched under ${sourceDir}`);
103
+ }
104
+ await mkdir(path.dirname(outputPath), {
105
+ recursive: true
106
+ });
107
+ await writeFile(outputPath, bytes);
108
+ const digest = createHash("sha256").update(bytes).digest("hex");
109
+ console.info(`\u2705 Reproducible source archive: ${outputPath}`);
110
+ console.info(` source_sha256=${digest}`);
111
+ }, "packageSource");
112
+
113
+ export { makeSourcePredicate, packageSource };
114
+ //# sourceMappingURL=LCHYL2IQ.js.map
115
+ //# sourceMappingURL=LCHYL2IQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/package-source.ts"],"names":["ARTIFACTS_DIR","NON_SOURCE_DIRS","Set","DEFAULT_INCLUDE_GLOBS","REQUIRED_ROOT_FILES","makeSourcePredicate","rootDirName","include","exclude","rootPrefix","defaultIncludePatterns","map","pattern","includePatterns","excludePatterns","relPath","type","startsWith","some","path","posix","matchesGlob","ZipEntryType","Directory","has","basename","packageSource","output","cwd","sourceDir","resolve","parentDir","dirname","outputPath","join","name","access","Error","relOutput","relative","isOutputInsideSource","isAbsolute","relOutputPosix","split","sep","isUnderArtifacts","includedFileCount","predicate","countingPredicate","entry","keep","File","bytes","zipDirectoryToUint8Array","pathInclusionPredicate","cause","mkdir","recursive","writeFile","digest","createHash","update","console","info"],"mappings":"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","file":"LCHYL2IQ.js","sourcesContent":["import { createHash } from 'node:crypto';\nimport { access, mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { PathInclusionPredicate, ZipEntryInfo } from '@layerzerolabs/deterministic-zip';\nimport { zipDirectoryToUint8Array, ZipEntryType } from '@layerzerolabs/deterministic-zip';\nimport type { ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';\n\n/**\n * Our own output directory. The predicate always prunes it, so it is the one place inside the\n * source tree the archive may be written to without contaminating itself (see `packageSource`).\n */\nconst ARTIFACTS_DIR = '.artifacts';\n\n/**\n * Directories the zip walker never descends into: build output, dependency installs, VCS, local\n * tool caches/credentials, and our own output. Returning `false` for these directory entries\n * prunes the subtree in DeterministicZip (so nested symlinks under `node_modules` are never\n * visited). The actual content filter is the include-only allow-list below.\n */\nconst NON_SOURCE_DIRS = new Set<string>([\n // build / cache output\n 'target',\n 'docker-target',\n 'dist',\n '.turbo',\n // dependency installs — the self-contained copy lives in dependencies/\n 'node_modules',\n // vcs / ci\n '.git',\n '.github',\n // local tool config / caches / credentials\n '.cargo',\n '.soroban',\n '.stellar',\n '.aws',\n '.claude',\n // stellar test artifacts\n 'test_snapshots',\n // our own output directory\n ARTIFACTS_DIR,\n]);\n\n/**\n * Default-deny allow-list: crate-relative globs for files a reproducible Rust/Soroban build needs.\n * Prefixed with `rootDirName/` at match time (same as `--include`). A file is packaged only if it\n * matches one of these (or a user `--include`). Everything else is dropped, so a stray or\n * misspelled secret file (`.env`, `*.key`, `credentials.json`, …) can never leak. Opt other\n * build-time assets in with `--include`.\n *\n * Patterns cover Rust sources, lockfiles, Cargo manifests anywhere under the crate,\n * `rust-toolchain.toml` / `rustfmt.toml` / `clippy.toml` at the crate root only (not nested\n * copies).\n */\nconst DEFAULT_INCLUDE_GLOBS = [\n '**/*.rs',\n '**/*.lock',\n '**/Cargo.toml',\n 'rust-toolchain.toml',\n 'rustfmt.toml',\n 'clippy.toml',\n] as const;\n\n/** Manifest + lockfile required at the crate root for a reproducible Cargo/Soroban package. */\nconst REQUIRED_ROOT_FILES = ['Cargo.toml', 'Cargo.lock'] as const;\n\nexport interface SourcePredicateOptions {\n /**\n * Top-level archive folder name — the basename of the crate directory (e.g. `stellar`).\n * Every kept entry must be this folder or live under it.\n */\n rootDirName: string;\n /**\n * Native Node glob patterns, relative to the crate root, for build assets the defaults miss\n * (e.g. `config/app.json`, `assets/**`). Use '/' as the separator.\n */\n include?: string[];\n /**\n * Native Node glob patterns, relative to the crate root, to drop even when they match the\n * default allow-list or `--include`. Always wins over include. Same matching as `--include`\n * (`path.posix.matchesGlob`); e.g. `tests/**` excludes files under `tests/`.\n */\n exclude?: string[];\n}\n\n/**\n * Include-only predicate for zipping the crate's parent directory.\n *\n * Keeps only paths under `rootDirName/`, prunes `NON_SOURCE_DIRS`, applies optional `--exclude`\n * (always wins), and for files applies the default-deny allow-list (plus optional `--include`\n * patterns prefixed with `rootDirName/`). Symlinks are not handled here — DeterministicZip throws\n * if it encounters one outside a pruned directory.\n */\nexport const makeSourcePredicate = ({\n rootDirName,\n include = [],\n exclude = [],\n}: SourcePredicateOptions): PathInclusionPredicate => {\n const rootPrefix = `${rootDirName}/`;\n const defaultIncludePatterns = DEFAULT_INCLUDE_GLOBS.map(\n (pattern) => `${rootDirName}/${pattern}`,\n );\n const includePatterns = include.map((pattern) => `${rootDirName}/${pattern}`);\n const excludePatterns = exclude.map((pattern) => `${rootDirName}/${pattern}`);\n\n return ({ relPath, type }: ZipEntryInfo): boolean => {\n if (relPath !== rootDirName && !relPath.startsWith(rootPrefix)) {\n return false;\n }\n\n if (excludePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern))) {\n return false;\n }\n\n if (type === ZipEntryType.Directory) {\n if (NON_SOURCE_DIRS.has(path.posix.basename(relPath))) return false;\n return true;\n }\n\n return (\n defaultIncludePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern)) ||\n includePatterns.some((pattern) => path.posix.matchesGlob(relPath, pattern))\n );\n };\n};\n\nexport interface PackageSourceOptions {\n /** Output .zip path; default <cwd>/.artifacts/<basename>-source.zip. */\n output?: string;\n /** Native Node glob patterns for entries to include beyond the default source extensions. */\n include?: string[];\n /** Native Node glob patterns to drop; always wins over the allow-list and `--include`. */\n exclude?: string[];\n}\n\n/**\n * Package the self-contained crate in `cwd` into a byte-deterministic source .zip and print its\n * SHA-256 (for `--meta source_sha256=…`).\n *\n * Zips the parent of `cwd` via DeterministicZip with a predicate that keeps only paths under the\n * crate basename (e.g. `stellar/…`), so the archive extracts into exactly one top-level folder\n * named after the crate. Filtering is include-only: only `.rs`, `.lock`, `Cargo.toml`, root\n * `rust-toolchain.toml` / `rustfmt.toml` / `clippy.toml`, and anything named by `--include` are\n * packaged; `--exclude` always wins over that allow-list. Non-source directories (`node_modules`,\n * `target`, …) are pruned by the predicate. Symlinks outside those pruned dirs cause\n * DeterministicZip to throw.\n *\n * The archive is written under `.artifacts/` by default; a custom `--output` must be outside the\n * source tree or under `.artifacts/`, else it is rejected. `Cargo.toml` and `Cargo.lock` must\n * exist at the crate root.\n */\nexport const packageSource = async (\n { output, include = [], exclude = [] }: PackageSourceOptions,\n { cwd }: Pick<ToolCommandExecutionOptions, 'cwd'>,\n): Promise<void> => {\n const sourceDir = path.resolve(cwd);\n const rootDirName = path.basename(sourceDir);\n const parentDir = path.dirname(sourceDir);\n const outputPath = output\n ? path.resolve(sourceDir, output)\n : path.join(sourceDir, ARTIFACTS_DIR, `${rootDirName}-source.zip`);\n\n for (const name of REQUIRED_ROOT_FILES) {\n try {\n await access(path.join(sourceDir, name));\n } catch {\n throw new Error(\n `${name} must exist at the crate root to package a reproducible source archive ` +\n `(looked for ${path.join(sourceDir, name)})`,\n );\n }\n }\n\n // The archive is built by walking parentDir; the only safe in-tree output location is the\n // always-pruned .artifacts/ dir. Reject any other output inside sourceDir.\n const relOutput = path.relative(sourceDir, outputPath);\n const isOutputInsideSource =\n relOutput !== '' && !relOutput.startsWith('..') && !path.isAbsolute(relOutput);\n const relOutputPosix = relOutput.split(path.sep).join('/');\n // Must be a path *under* .artifacts/ (e.g. .artifacts/foo.zip). Exact `.artifacts` would\n // resolve to a file named `.artifacts` in the crate root and break later default writes.\n const isUnderArtifacts = relOutputPosix.startsWith(`${ARTIFACTS_DIR}/`);\n if (isOutputInsideSource && !isUnderArtifacts) {\n throw new Error(\n `--output must be under ${ARTIFACTS_DIR}/ or outside the source directory, got ` +\n `\"${relOutputPosix}\". Any other location inside ${sourceDir} would be captured in ` +\n `the archive and break reproducibility.`,\n );\n }\n\n // Count included files so an all-non-source tree throws instead of writing a fileless archive.\n let includedFileCount = 0;\n const predicate = makeSourcePredicate({ rootDirName, include, exclude });\n const countingPredicate: PathInclusionPredicate = (entry) => {\n const keep = predicate(entry);\n if (keep && entry.type === ZipEntryType.File) includedFileCount += 1;\n return keep;\n };\n\n let bytes: Uint8Array;\n try {\n bytes = await zipDirectoryToUint8Array(parentDir, {\n pathInclusionPredicate: countingPredicate,\n });\n } catch (cause) {\n throw new Error(`Failed to package source: ${sourceDir}`, { cause });\n }\n\n if (includedFileCount === 0) {\n throw new Error(`Failed to package source: no source files matched under ${sourceDir}`);\n }\n\n await mkdir(path.dirname(outputPath), { recursive: true });\n await writeFile(outputPath, bytes);\n\n const digest = createHash('sha256').update(bytes).digest('hex');\n console.info(`✅ Reproducible source archive: ${outputPath}`);\n console.info(` source_sha256=${digest}`);\n};\n"]}
@@ -1,11 +1,9 @@
1
- import { init_esm_shims, __name } from './2VBLSQAK.js';
1
+ import { __name } from './VUOMXK5T.js';
2
2
  import { access, readFile } from 'fs/promises';
3
3
  import path from 'path';
4
4
  import { parse } from 'toml';
5
5
  import { executeToolCommand } from '@layerzerolabs/vm-tooling';
6
6
 
7
- // src/commands/sync-toolchain.ts
8
- init_esm_shims();
9
7
  var syncedCwds = /* @__PURE__ */ new Set();
10
8
  async function syncToolchain(context, options) {
11
9
  if (syncedCwds.has(options.cwd)) {
@@ -60,5 +58,5 @@ async function syncToolchain(context, options) {
60
58
  __name(syncToolchain, "syncToolchain");
61
59
 
62
60
  export { syncToolchain };
63
- //# sourceMappingURL=K7N3LKMZ.js.map
64
- //# sourceMappingURL=K7N3LKMZ.js.map
61
+ //# sourceMappingURL=P6KJGYNA.js.map
62
+ //# sourceMappingURL=P6KJGYNA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/sync-toolchain.ts"],"names":["syncedCwds","Set","syncToolchain","context","options","has","cwd","filePath","path","join","installCmd","hasToolchainFile","access","then","parsed","parse","readFile","channel","toolchain","Error","targets","components","installArgs","target","push","component","script","console","info","add","executeToolCommand","volumes","type","containerPath","name","shared","locked"],"mappings":";;;;;;AAeA,IAAMA,UAAAA,uBAAiBC,GAAAA,EAAAA;AAEvB,eAAsBC,aAAAA,CAClBC,SACAC,OAAAA,EAAoC;AAEpC,EAAA,IAAIJ,UAAAA,CAAWK,GAAAA,CAAID,OAAAA,CAAQE,GAAG,CAAA,EAAG;AAC7B,IAAA;AACJ,EAAA;AAEA,EAAA,MAAMC,QAAAA,GAAWC,IAAAA,CAAKC,IAAAA,CAAKL,OAAAA,CAAQE,KAAK,qBAAA,CAAA;AAExC,EAAA,IAAII,UAAAA;AACJ,EAAA,MAAMC,gBAAAA,GAAmB,MAAMC,MAAAA,CAAOL,QAAAA,EAAUM,IAAAA,CAC5C,MAAM,IAAA,EACN,MAAM,KAAA,CAAA;AAGV,EAAA,IAAIF,gBAAAA,EAAkB;AAClB,IAAA,MAAMG,SAA4BC,KAAAA,CAAM,MAAMC,QAAAA,CAAST,QAAAA,EAAU,OAAA,CAAA,CAAA;AAEjE,IAAA,MAAMU,OAAAA,GAAUH,OAAOI,SAAAA,EAAWD,OAAAA;AAClC,IAAA,IAAI,OAAOA,YAAY,QAAA,EAAU;AAC7B,MAAA,MAAM,IAAIE,KAAAA,CAAM,CAAA,+BAAA,EAAkCZ,QAAAA,CAAAA,CAAU,CAAA;AAChE,IAAA;AAEA,IAAA,MAAMa,OAAAA,GAAoBN,MAAAA,CAAOI,SAAAA,EAAWE,OAAAA,IAAW,EAAA;AACvD,IAAA,MAAMC,UAAAA,GAAuBP,MAAAA,CAAOI,SAAAA,EAAWG,UAAAA,IAAc,EAAA;AAO7D,IAAA,MAAMC,WAAAA,GAAc;AAAC,MAAA,CAAA,yBAAA,EAA4BL,OAAAA,CAAAA,iBAAAA;;AACjD,IAAA,KAAA,MAAWM,UAAUH,OAAAA,EAAS;AAC1BE,MAAAA,WAAAA,CAAYE,IAAAA,CAAK,CAAA,SAAA,EAAYD,MAAAA,CAAAA,CAAQ,CAAA;AACzC,IAAA;AACA,IAAA,KAAA,MAAWE,aAAaJ,UAAAA,EAAY;AAChCC,MAAAA,WAAAA,CAAYE,IAAAA,CAAK,CAAA,YAAA,EAAeC,SAAAA,CAAAA,CAAW,CAAA;AAC/C,IAAA;AAEAf,IAAAA,UAAAA,GAAaY,WAAAA,CAAYb,KAAK,GAAA,CAAA;EAClC,CAAA,MAAO;AAGHC,IAAAA,UAAAA,GAAa,uBAAA;AACjB,EAAA;AAKA,EAAA,MAAMgB,MAAAA,GAAS;AACX,IAAA,0BAAA;AACA,IAAA,2DAAA;AACAhB,IAAAA;AACFD,GAAAA,CAAAA,IAAAA,CAAK,MAAA,CAAA;AACPkB,EAAAA,OAAAA,CAAQC,IAAAA,CAAK,CAAA,kCAAA,EAA8BlB,UAAAA,CAAAA,CAAY,CAAA;AAGvDV,EAAAA,UAAAA,CAAW6B,GAAAA,CAAIzB,QAAQE,GAAG,CAAA;AAE1B,EAAA,MAAMwB,kBAAAA,CAAmB3B,OAAAA,EAAS,SAAA,EAAW,EAAA,EAAI;IAC7C,GAAGC,OAAAA;AACHsB,IAAAA,MAAAA;IACAK,OAAAA,EAAS;SACF3B,OAAAA,CAAQ2B,OAAAA;AACX,MAAA;QACIC,IAAAA,EAAM,SAAA;QACNC,aAAAA,EAAe,eAAA;QACfC,IAAAA,EAAM,gBAAA;QACNC,MAAAA,EAAQ,IAAA;QACRC,MAAAA,EAAQ;AACZ;;GAER,CAAA;AACJ;AA1EsBlC,MAAAA,CAAAA,aAAAA,EAAAA,eAAAA,CAAAA","file":"P6KJGYNA.js","sourcesContent":["import { access, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse } from 'toml';\n\nimport type { ChainContext, ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';\nimport { executeToolCommand } from '@layerzerolabs/vm-tooling';\n\ninterface RustToolchainToml {\n toolchain?: {\n channel?: string;\n targets?: string[];\n components?: string[];\n };\n}\n\nconst syncedCwds = new Set<string>();\n\nexport async function syncToolchain(\n context: ChainContext<string>,\n options: ToolCommandExecutionOptions,\n): Promise<void> {\n if (syncedCwds.has(options.cwd)) {\n return;\n }\n\n const filePath = path.join(options.cwd, 'rust-toolchain.toml');\n\n let installCmd: string;\n const hasToolchainFile = await access(filePath).then(\n () => true,\n () => false,\n );\n\n if (hasToolchainFile) {\n const parsed: RustToolchainToml = parse(await readFile(filePath, 'utf-8'));\n\n const channel = parsed.toolchain?.channel;\n if (typeof channel !== 'string') {\n throw new Error(`Missing 'toolchain.channel' in ${filePath}`);\n }\n\n const targets: string[] = parsed.toolchain?.targets ?? [];\n const components: string[] = parsed.toolchain?.components ?? [];\n\n // --no-self-update: rustup's self-update downloads a new binary to\n // $CARGO_HOME/bin/rustup-init and chmod's it. Inside Docker the\n // download can fail, leaving no file for chmod → \"failed to set\n // permissions: No such file or directory\". The rustup version is\n // pinned by the Docker image so self-update is unnecessary.\n const installArgs = [`rustup toolchain install ${channel} --no-self-update`];\n for (const target of targets) {\n installArgs.push(`--target ${target}`);\n }\n for (const component of components) {\n installArgs.push(`--component ${component}`);\n }\n\n installCmd = installArgs.join(' ');\n } else {\n // No rust-toolchain.toml found — install stable as the default so that\n // cargo (a rustup proxy) can resolve a toolchain from the empty RUSTUP_HOME volume.\n installCmd = 'rustup default stable';\n }\n\n // rustup expects to find itself at $CARGO_HOME/bin/rustup to manage proxy\n // binaries there. At runtime CARGO_HOME points to /cache/cargo (volume),\n // so we symlink the image-installed rustup binary into the volume.\n const script = [\n 'mkdir -p $CARGO_HOME/bin',\n 'ln -sf /usr/local/cargo/bin/rustup $CARGO_HOME/bin/rustup',\n installCmd,\n ].join(' && ');\n console.info(`🔧 Syncing Rust toolchain: ${installCmd}`);\n\n // Mark as synced before executeToolCommand to prevent recursive preExecute calls\n syncedCwds.add(options.cwd);\n\n await executeToolCommand(context, 'stellar', [], {\n ...options,\n script,\n volumes: [\n ...options.volumes,\n {\n type: 'isolate',\n containerPath: '/cache/rustup',\n name: 'stellar-rustup',\n shared: true,\n locked: true,\n },\n ],\n });\n}\n"]}
@@ -0,0 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ export { __name };
5
+ //# sourceMappingURL=VUOMXK5T.js.map
6
+ //# sourceMappingURL=VUOMXK5T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"VUOMXK5T.js"}
@@ -0,0 +1,55 @@
1
+ import type { PathInclusionPredicate } from '@layerzerolabs/deterministic-zip';
2
+ import type { ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';
3
+ export interface SourcePredicateOptions {
4
+ /**
5
+ * Top-level archive folder name — the basename of the crate directory (e.g. `stellar`).
6
+ * Every kept entry must be this folder or live under it.
7
+ */
8
+ rootDirName: string;
9
+ /**
10
+ * Native Node glob patterns, relative to the crate root, for build assets the defaults miss
11
+ * (e.g. `config/app.json`, `assets/**`). Use '/' as the separator.
12
+ */
13
+ include?: string[];
14
+ /**
15
+ * Native Node glob patterns, relative to the crate root, to drop even when they match the
16
+ * default allow-list or `--include`. Always wins over include. Same matching as `--include`
17
+ * (`path.posix.matchesGlob`); e.g. `tests/**` excludes files under `tests/`.
18
+ */
19
+ exclude?: string[];
20
+ }
21
+ /**
22
+ * Include-only predicate for zipping the crate's parent directory.
23
+ *
24
+ * Keeps only paths under `rootDirName/`, prunes `NON_SOURCE_DIRS`, applies optional `--exclude`
25
+ * (always wins), and for files applies the default-deny allow-list (plus optional `--include`
26
+ * patterns prefixed with `rootDirName/`). Symlinks are not handled here — DeterministicZip throws
27
+ * if it encounters one outside a pruned directory.
28
+ */
29
+ export declare const makeSourcePredicate: ({ rootDirName, include, exclude, }: SourcePredicateOptions) => PathInclusionPredicate;
30
+ export interface PackageSourceOptions {
31
+ /** Output .zip path; default <cwd>/.artifacts/<basename>-source.zip. */
32
+ output?: string;
33
+ /** Native Node glob patterns for entries to include beyond the default source extensions. */
34
+ include?: string[];
35
+ /** Native Node glob patterns to drop; always wins over the allow-list and `--include`. */
36
+ exclude?: string[];
37
+ }
38
+ /**
39
+ * Package the self-contained crate in `cwd` into a byte-deterministic source .zip and print its
40
+ * SHA-256 (for `--meta source_sha256=…`).
41
+ *
42
+ * Zips the parent of `cwd` via DeterministicZip with a predicate that keeps only paths under the
43
+ * crate basename (e.g. `stellar/…`), so the archive extracts into exactly one top-level folder
44
+ * named after the crate. Filtering is include-only: only `.rs`, `.lock`, `Cargo.toml`, root
45
+ * `rust-toolchain.toml` / `rustfmt.toml` / `clippy.toml`, and anything named by `--include` are
46
+ * packaged; `--exclude` always wins over that allow-list. Non-source directories (`node_modules`,
47
+ * `target`, …) are pruned by the predicate. Symlinks outside those pruned dirs cause
48
+ * DeterministicZip to throw.
49
+ *
50
+ * The archive is written under `.artifacts/` by default; a custom `--output` must be outside the
51
+ * source tree or under `.artifacts/`, else it is rejected. `Cargo.toml` and `Cargo.lock` must
52
+ * exist at the crate root.
53
+ */
54
+ export declare const packageSource: ({ output, include, exclude }: PackageSourceOptions, { cwd }: Pick<ToolCommandExecutionOptions, "cwd">) => Promise<void>;
55
+ //# sourceMappingURL=package-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-source.d.ts","sourceRoot":"","sources":["../../src/commands/package-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,kCAAkC,CAAC;AAE7F,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AA4D7E,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,oCAIjC,sBAAsB,KAAG,sBA2B3B,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACjC,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,GACtB,8BAAwC,oBAAoB,EAC5D,SAAS,IAAI,CAAC,2BAA2B,EAAE,KAAK,CAAC,KAClD,OAAO,CAAC,IAAI,CAgEd,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { makeSourcePredicate, packageSource } from '../LCHYL2IQ.js';
2
+ import '../VUOMXK5T.js';
3
+ //# sourceMappingURL=package-source.js.map
4
+ //# sourceMappingURL=package-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"package-source.js"}
@@ -1,4 +1,4 @@
1
- export { syncToolchain } from '../K7N3LKMZ.js';
2
- import '../2VBLSQAK.js';
1
+ export { syncToolchain } from '../P6KJGYNA.js';
2
+ import '../VUOMXK5T.js';
3
3
  //# sourceMappingURL=sync-toolchain.js.map
4
4
  //# sourceMappingURL=sync-toolchain.js.map
@@ -6,13 +6,31 @@ import type { ToolCommandExecutionOptions } from '@layerzerolabs/vm-tooling';
6
6
  */
7
7
  export declare const officialImageTagRef: (stellarVersion: string, rustVersion: string) => string;
8
8
  export declare const parseAmd64Digest: (manifestInspectJson: string) => string;
9
+ /**
10
+ * Canonicalize `stellar contract build` args so the embedded metadata order is stable.
11
+ *
12
+ * Soroban stores contract metadata as an ORDERED sequence, so the order of `--meta key=value`
13
+ * flags changes the WASM bytes (verified: swapping two `--meta` flags yields a different WASM
14
+ * hash). To keep the build reproducible regardless of the order the caller passed `--meta`, every
15
+ * meta entry — the caller's plus the tool-injected ones — is pulled out, merged, and re-emitted in
16
+ * sorted order. Non-meta args keep their original relative order and precede the sorted metas.
17
+ *
18
+ * Injected keys (e.g. `bldimg`) are tool-controlled and RESERVED: any caller `--meta` reusing an
19
+ * injected key is dropped, so a caller can never override the recorded build image by key
20
+ * collision (before sorting, the injected entry was always appended last and won on its own).
21
+ *
22
+ * Both `--meta k=v` and `--meta=k=v` forms are recognized; a dangling `--meta` with no value (or
23
+ * one followed by another flag) is dropped.
24
+ */
25
+ export declare const canonicalizeMetaArgs: (buildArgs: string[], injectedMeta: string[]) => string[];
9
26
  /**
10
27
  * Assemble the `docker run` argv for a verifiable build. Kept pure and synchronous so the mount /
11
28
  * workdir layout and the tool-injected `--meta bldimg=…` are unit-testable without Docker.
12
29
  *
13
30
  * The official image's ENTRYPOINT is `stellar`, so the trailing `contract build …` runs under it.
14
31
  * The source directory is assumed self-contained, so it is mounted at /source and built in place —
15
- * no surrounding workspace is required.
32
+ * no surrounding workspace is required. All `--meta` flags (the caller's plus the injected
33
+ * `bldimg`) are sorted into a canonical order so the WASM hash is independent of `--meta` ordering.
16
34
  */
17
35
  export declare const buildVerifiableBuildDockerArgs: ({ imageRef, sourceDir, buildArgs, bldimg, }: {
18
36
  imageRef: string;
@@ -20,6 +38,15 @@ export declare const buildVerifiableBuildDockerArgs: ({ imageRef, sourceDir, bui
20
38
  buildArgs: string[];
21
39
  bldimg: string;
22
40
  }) => string[];
41
+ /**
42
+ * Resolve the directory to build. An explicit `sourceDir` that is relative resolves against the
43
+ * cwd; an absolute one is used as-is; omitting it falls back to the cwd. Kept pure/synchronous so
44
+ * the cwd-vs-explicit-folder precedence is unit-testable without Docker.
45
+ *
46
+ * This is what lets the pipeline decompress a packaged source archive into a scratch directory and
47
+ * build that, instead of always building the process cwd.
48
+ */
49
+ export declare const resolveBuildDir: (cwd: string, sourceDir?: string) => string;
23
50
  export interface VerifiableBuildVersions {
24
51
  stellarVersion: string;
25
52
  rustVersion: string;
@@ -43,6 +70,6 @@ export interface VerifiableBuildVersions {
43
70
  * as its own user/toolchain.
44
71
  */
45
72
  export declare class VerifiableBuildWrapper {
46
- run(args: string[], { stellarVersion, rustVersion }: VerifiableBuildVersions, options: ToolCommandExecutionOptions): Promise<void>;
73
+ run(args: string[], { stellarVersion, rustVersion }: VerifiableBuildVersions, options: ToolCommandExecutionOptions, sourceDir?: string): Promise<void>;
47
74
  }
48
75
  //# sourceMappingURL=verifiable-build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verifiable-build.d.ts","sourceRoot":"","sources":["../../src/commands/verifiable-build.ts"],"names":[],"mappings":"AAGA,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;AAqBF;;;;;;;GAOG;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,EAgBT,CAAC;AAuBF,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,GACrC,OAAO,CAAC,IAAI,CAAC;CAoBnB"}
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,4 +1,4 @@
1
- export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, officialImageTagRef, parseAmd64Digest } from '../6YPWRWU3.js';
2
- import '../2VBLSQAK.js';
1
+ export { VerifiableBuildWrapper, buildVerifiableBuildDockerArgs, canonicalizeMetaArgs, officialImageTagRef, parseAmd64Digest, resolveBuildDir } from '../EP3GEVT6.js';
2
+ import '../VUOMXK5T.js';
3
3
  //# sourceMappingURL=verifiable-build.js.map
4
4
  //# sourceMappingURL=verifiable-build.js.map
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
- export { images, tools, versionCombinations } from './PT2VYI7I.js';
2
- import './K7N3LKMZ.js';
3
- import './2VBLSQAK.js';
1
+ export { images, tools, versionCombinations } from './AY7HGKNR.js';
2
+ import './P6KJGYNA.js';
3
+ import './VUOMXK5T.js';
4
4
  //# sourceMappingURL=config.js.map
5
5
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,IAAI,QAAO,OAAO,CAAC,IAAI,CAkD9B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,IAAI,QAAO,OAAO,CAAC,IAAI,CA6F9B,CAAC"}
package/dist/index.js CHANGED
@@ -1,11 +1,10 @@
1
- import { VerifiableBuildWrapper } from './6YPWRWU3.js';
2
- import { versionCombinations, images, tools } from './PT2VYI7I.js';
3
- import { syncToolchain } from './K7N3LKMZ.js';
4
- import { init_esm_shims, __name } from './2VBLSQAK.js';
1
+ import { packageSource } from './LCHYL2IQ.js';
2
+ import { VerifiableBuildWrapper } from './EP3GEVT6.js';
3
+ import { versionCombinations, images, tools } from './AY7HGKNR.js';
4
+ import { syncToolchain } from './P6KJGYNA.js';
5
+ import { __name } from './VUOMXK5T.js';
5
6
  import { runCli } from '@layerzerolabs/vm-tooling';
6
7
 
7
- // src/index.ts
8
- init_esm_shims();
9
8
  var context = {
10
9
  tools,
11
10
  images,
@@ -16,9 +15,14 @@ var main = /* @__PURE__ */ __name(() => runCli(context, (program, parseGlobalOpt
16
15
  program.command("sync-toolchain").description("Pre-download the Rust toolchain specified in rust-toolchain.toml under a lock").action(async () => syncToolchain(context, await parseGlobalOptions(program)));
17
16
  const extra = program.command("extra").description("Extra commands for VM tooling");
18
17
  const stellar = extra.command("stellar");
19
- stellar.command("verifiable-build").description("Reproducible `stellar contract build` of the self-contained source in the cwd, inside the official stellar/stellar-cli:<stellar>-rust<rust>-slim-bookworm image pinned by its linux/amd64 digest (run from the host, no Docker socket; embeds the bldimg WASM meta automatically)").requiredOption("--stellar-version <version>", "Stellar CLI version of the official reproducible image (e.g. 25.1.0)").requiredOption("--rust-version <version>", "Rust version of the official reproducible image (e.g. 1.90.0)").argument("[args...]", "Arguments for `stellar contract build`, after `--` (e.g. -- --package <crate>)").passThroughOptions(true).allowUnknownOption().action(async (args, { stellarVersion, rustVersion }) => verifiableBuildWrapper.run(args, {
18
+ stellar.command("verifiable-build").description("Reproducible `stellar contract build` of the self-contained source in the cwd by default, inside the official stellar/stellar-cli:<stellar>-rust<rust>-slim-bookworm image pinned by its linux/amd64 digest (run from the host, no Docker socket; embeds the bldimg WASM meta automatically)").requiredOption("--stellar-version <version>", "Stellar CLI version of the official reproducible image (e.g. 25.1.0)").requiredOption("--rust-version <version>", "Rust version of the official reproducible image (e.g. 1.90.0)").option("--source-dir <path>", "Directory to build \u2014 the self-contained/decompressed source. Relative paths resolve against the cwd; defaults to the cwd.").argument("[args...]", "Arguments for `stellar contract build`, after `--` (e.g. -- --package <crate>)").passThroughOptions(true).allowUnknownOption().action(async (args, { stellarVersion, rustVersion, sourceDir }) => verifiableBuildWrapper.run(args, {
20
19
  stellarVersion,
21
20
  rustVersion
21
+ }, await parseGlobalOptions(program), sourceDir));
22
+ stellar.command("package-source").description("Package the self-contained crate in the cwd into a byte-deterministic source .zip under .artifacts/ (for the SEP-58 verifiable build) and print its source_sha256. Include-only: packages source files (.rs/.lock, Cargo.toml, rust-toolchain.toml, rustfmt.toml, clippy.toml) plus any --include entries; --exclude always wins. Skips non-source directories (target, node_modules, \u2026).").option("--output <path>", "Output .zip path (default: <cwd>/.artifacts/<basename>-source.zip)").option("--include <pattern...>", "Native Node glob patterns to include beyond the default source extensions", []).option("--exclude <pattern...>", "Native Node glob patterns to exclude (always wins over the allow-list and --include)", []).action(async ({ output, include, exclude }) => packageSource({
23
+ output,
24
+ include,
25
+ exclude
22
26
  }, await parseGlobalOptions(program)));
23
27
  }), "main");
24
28