From 611288b53116ad16e6444c47722c18fb87e6965b Mon Sep 17 00:00:00 2001 From: peachbits Date: Tue, 14 Jul 2026 22:53:24 -0700 Subject: [PATCH] Move gRPC/NIO deps off CocoaPods; vendor them as provider-or-consumer PirateLightClientKit depends on grpc-swift, whose CocoaPods releases stopped at 1.8.0 (1.24+ is SwiftPM-only). This package still pulled gRPC-Swift ~> 1.8 + SQLite.swift as CocoaPods dependencies, pinning the grpc/NIO stack to a 2023-era version that collides with react-native-zcash's vendored grpc-swift 1.27 when both pods ship in one app: two grpc stacks at different versions on one app link line, resolution decided by link order. Debug (-Onone) masked it; Release surfaced it as undefined DequeModule/NIO-internal symbols. Convert to the same compile-SDK-in-pod + vendored-SwiftPM-deps architecture as react-native-zcash, unifying the graph at one set of versions: - scripts/buildVendoredDeps.ts: builds a throwaway SwiftPM wrapper against the SDK, merges the dep graph into libPirateDeps.xcframework (device arm64 + fat sim) and harvests the dep .swiftmodules + C module.modulemaps. Pinned by scripts/depsPackage.resolved. - scripts/depsPackage.resolved: the graph pinned to the EXACT versions react-native-zcash resolves (grpc-swift 1.27.3, swift-nio 2.95.0, SwiftProtobuf 1.35.1, SQLite.swift 0.15.5, ...); the Pirate SDK's Package.swift uses open ranges so this keeps the two packages in lockstep. - podspec: drops the gRPC-Swift/SQLite.swift CocoaPods dependencies; compiles the in-pod SDK source against the harvested modules; adds a Swift-compiler fail-fast stamp check. Provider OR consumer, host app chooses: two copies of the same graph on one link line collide under -ObjC (force-loads every Swift archive member). PROVIDER (default) links its own libPirateDeps.xcframework and is self-contained. CONSUMER (host sets ENV['RN_PIRATECHAIN_VENDOR_DEPS']='false' in its Podfile, e.g. Edge alongside react-native-zcash) omits its archive from the link and resolves grpc/NIO symbols from the sibling's. depsPackage.resolved + the compiler stamp make the two archives ABI-interchangeable. Validated on Edge develop (RN 0.79, iOS 15.6) Release, pirate as CONSUMER: 0 gRPC/NIO CocoaPods, BUILD SUCCEEDED, 0 undefined, 0 duplicate-symbol errors (256 remaining dup WARNINGS are the pre-existing libpiratelc-vs-libzcashlc Rust-core sqlite3/rust_eh_personality overlap). Provider archive verified complete (GRPC/NIOCore/SwiftProtobuf symbols, device + fat-sim slices). Co-Authored-By: Claude Opus 4.8 --- .gitignore | 1 + react-native-piratechain.podspec | 86 +++++++- scripts/buildVendoredDeps.ts | 364 +++++++++++++++++++++++++++++++ scripts/depsPackage.resolved | 202 +++++++++++++++++ scripts/updateSources.ts | 5 + 5 files changed, 655 insertions(+), 3 deletions(-) create mode 100644 scripts/buildVendoredDeps.ts create mode 100644 scripts/depsPackage.resolved diff --git a/.gitignore b/.gitignore index 1863282..e43a248 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /ios/libpiratelc.h /ios/libpiratelc.xcframework/ /ios/PirateLightClientKit/ +/ios/vendored/ /lib/ /tmp/ diff --git a/react-native-piratechain.podspec b/react-native-piratechain.podspec index f4e7bf7..821a520 100644 --- a/react-native-piratechain.podspec +++ b/react-native-piratechain.podspec @@ -2,6 +2,40 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) +# Each bundled C dep module (ios/vendored/cmodules// — headers + +# module.modulemap) becomes one relative clang include path, so the in-pod +# PirateLightClientKit source can resolve the C modules that the pre-built +# Swift dependency modules (SwiftNIO / GRPC) import. +cmodule_flags = Dir.glob(File.join(__dir__, "ios/vendored/cmodules/*")) + .select { |p| File.directory?(p) } + .map { |p| "-Xcc -I\"$(PODS_TARGET_SRCROOT)/ios/vendored/cmodules/#{File.basename(p)}\"" } + .join(" ") + +# The pre-built Swift modules under ios/vendored/ are only readable by the +# EXACT Swift compiler that produced them (the binary .swiftmodule format is +# not stable across compilers, and the stable alternative — library-evolution +# .swiftinterface — is unavailable because swift-nio rejects evolution builds +# by upstream policy; see apple/swift-nio#2470/#2897, closed "not planned"). +# Fail fast with instructions instead of letting the build die later on a +# cryptic "module compiled with Swift X cannot be imported by Swift Y" error. +stamp_path = File.join(__dir__, "ios/vendored/swift-version.txt") +if File.exist?(stamp_path) + built_with = File.read(stamp_path).strip + local_swift = `xcrun swift --version 2>/dev/null`[/swiftlang-[0-9.]+/] + if !built_with.empty? && !local_swift.nil? && built_with != local_swift + raise <<~MSG + react-native-piratechain: the prebuilt Swift dependency modules in + ios/vendored/ were built with #{built_with}, but this machine's Swift + compiler is #{local_swift}. Binary .swiftmodule files only load under the + exact compiler that produced them. + + Fix: rebuild the vendored dependencies with your toolchain: + cd node_modules/react-native-piratechain && npm run update-sources + (or switch to the Xcode whose Swift is #{built_with}) + MSG + end +end + Pod::Spec.new do |s| s.name = package['name'] s.version = package['version'] @@ -15,6 +49,10 @@ Pod::Spec.new do |s| :git => "https://github.com/EdgeApp/react-native-piratechain.git", :tag => "v#{s.version}" } + + # The bridge + the vendored PirateLightClientKit Swift source, compiled + # in-pod as ONE module (so the bridge uses SDK types directly — see copySwift + # in scripts/updateSources.ts). s.source_files = "ios/libpiratelc.h", "ios/react-native-piratechain-Bridging-Header.h", @@ -25,10 +63,52 @@ Pod::Spec.new do |s| "piratechain-mainnet" => "ios/PirateLightClientKit/Resources/piratesaplingtree-checkpoints/mainnet/*.json", "piratechain-testnet" => "ios/PirateLightClientKit/Resources/piratesaplingtree-checkpoints/testnet/*.json" } - s.vendored_frameworks = "ios/libpiratelc.xcframework" s.dependency "MnemonicSwift", "~> 2.2" - s.dependency "gRPC-Swift", "~> 1.8" - s.dependency "SQLite.swift/standalone", "~> 0.14" s.dependency "React-Core" + + # --------------------------------------------------------------------------- + # The SDK's SwiftPM dependencies (grpc-swift, SwiftNIO, SwiftProtobuf, + # SQLite.swift) pre-built into libPirateDeps.xcframework, plus their Swift and + # C modules (ios/vendored/modules + cmodules) that the in-pod + # PirateLightClientKit source imports at compile time. grpc-swift 1.24+ ships + # SwiftPM-only with no podspec, so these can no longer be CocoaPods + # `dependency`s; vendoring them as a static binary keeps the host app on + # STATIC frameworks. + # + # PROVIDER / CONSUMER — the host app chooses: + # react-native-zcash links the SAME dependency graph and vendors it the same + # way. Two copies of that graph on one app link line collide under the app's + # -ObjC flag (it force-loads every Swift archive member → tens of thousands of + # duplicate symbols), so exactly ONE pod may put the graph on the link line. + # * PROVIDER (default): this pod links its own libPirateDeps.xcframework and + # is fully self-contained — correct for any app that uses piratechain + # without react-native-zcash. + # * CONSUMER: an app that ALSO installs react-native-zcash (e.g. Edge) sets + # ENV['RN_PIRATECHAIN_VENDOR_DEPS'] = 'false' + # in its Podfile. This pod then omits its own archive from the link and its + # grpc/NIO symbols resolve from zcash's archive instead. In BOTH modes the + # in-pod SDK source still compiles against the modules below. + # scripts/depsPackage.resolved pins this graph to the EXACT versions + # react-native-zcash resolves, so the two archives are interchangeable — keep + # them in lockstep when react-native-zcash bumps its SDK. + # + # sqlite3 is not in this binary: on Apple platforms SQLite.swift has no C-shim + # target — it imports the system `sqlite3` clang module. (Edge's pre-existing + # duplicate-sqlite3 ld WARNINGS come from libpiratelc vs libzcashlc, the two + # Rust cores, and are unrelated to this package's deps binary.) + # + # Regenerate ios/vendored/ with `npm run update-sources` + # (scripts/buildVendoredDeps.ts). + # --------------------------------------------------------------------------- + vendor_deps = ENV['RN_PIRATECHAIN_VENDOR_DEPS'] != 'false' + vendored_frameworks = ["ios/libpiratelc.xcframework"] # the Rust core, always + vendored_frameworks << "ios/vendored/libPirateDeps.xcframework" if vendor_deps + s.vendored_frameworks = vendored_frameworks + + s.preserve_paths = "ios/vendored/**/*" + s.pod_target_xcconfig = { + "SWIFT_INCLUDE_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ios/vendored/modules\"", + "OTHER_SWIFT_FLAGS" => cmodule_flags + } end diff --git a/scripts/buildVendoredDeps.ts b/scripts/buildVendoredDeps.ts new file mode 100644 index 0000000..8353d99 --- /dev/null +++ b/scripts/buildVendoredDeps.ts @@ -0,0 +1,364 @@ +// Builds the SwiftPM dependency graph that the vendored PirateLightClientKit +// source links against — grpc-swift, SwiftNIO, SwiftProtobuf, SQLite.swift and +// their C shims — into ONE static library per platform packaged as an +// XCFramework, plus the Swift `.swiftmodule`s and C `module.modulemap`s the +// in-pod SDK source needs to `import` them. +// +// Why this exists: as of the modern SDK, grpc-swift (1.24+) ships SwiftPM-only +// with no podspec, so it can no longer be a CocoaPods `dependency`. Instead of +// forcing the whole host app onto dynamic frameworks (the only way to consume +// the SDK via `spm_dependency`), we pre-build just these leaf dependencies into +// a static binary. The host app stays on static frameworks; the SDK *source* +// keeps compiling in-pod exactly as before (see copySwift in updateSources.ts). +// +// PROVIDER / CONSUMER (read this before touching the podspec): +// react-native-zcash links the SAME dependency graph and vendors it the same +// way. The Edge app ships BOTH pods. Two copies of the graph on one app link +// line collide under the app's `-ObjC` flag (it force-loads every Swift archive +// member → tens of thousands of duplicate symbols). So exactly ONE pod may put +// the graph on the link line. This package builds and ships everything needed +// to be the PROVIDER (the default — it works standalone), but the podspec lets +// the host app demote it to a CONSUMER (RN_PIRATECHAIN_VENDOR_DEPS=false) when +// another pod already provides an identical copy. In CONSUMER mode this pod +// still compiles its in-pod source against the harvested modules, but omits its +// own libPirateDeps.xcframework from the link; its grpc/NIO symbols resolve +// from the provider's archive. The invariant that makes that safe: +// scripts/depsPackage.resolved pins this graph to the EXACT versions +// react-native-zcash resolves, so the two archives are interchangeable. +// +// Output (all under ios/vendored/, gitignored, shipped in the npm tarball): +// libPirateDeps.xcframework - merged static lib (device arm64; sim arm64+x86_64) +// modules/.swiftmodule - Swift dep modules (all arch slices) +// cmodules// - C dep modules (headers + module.modulemap) +// swift-version.txt - the Swift compiler that produced the modules +// +// Compiler coupling: the binary .swiftmodule format is only readable by the +// exact Swift compiler that wrote it (library-evolution .swiftinterface is not +// an option: swift-nio rejects evolution builds by upstream policy — see +// apple/swift-nio#2470/#2897, closed "not planned"). swift-version.txt records +// the producing compiler so the podspec can fail fast with instructions when +// the consuming Xcode doesn't match. + +import { execFileSync } from 'child_process' +import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from 'fs' +import { join } from 'path' + +// This repo's @types/node predates fs.cpSync/rmSync, and the sibling scripts +// already shell out for file ops, so do the same here. +function rm(path: string): void { + execFileSync('rm', ['-rf', path]) +} +function cp(src: string, dest: string): void { + execFileSync('cp', ['-R', src, dest]) +} + +const root = join(__dirname, '..') +const tmp = join(root, 'tmp') +const sdkClone = join(tmp, 'PirateLightClientKit') +const wrapper = join(tmp, 'deps-wrapper') +const vendored = join(root, 'ios/vendored') + +// Checked-in dependency pins for the wrapper build. The Pirate SDK repo does +// not commit a Package.resolved (its Package.swift uses open ranges like +// grpc-swift `from: 1.14.0`), so this snapshot pins the graph to the SAME +// versions react-native-zcash's SDK resolves — the PROVIDER/CONSUMER invariant. +const DEPS_RESOLVED = join(__dirname, 'depsPackage.resolved') + +// Targets that must NOT go into the deps binary: +// - PirateLightClientKit: compiled in-pod from source, not vendored as a binary +// - PirateDepsWrapper: our throwaway entry-point target +// (libpiratelc is a binary target — no objects to merge; it ships separately +// as ios/libpiratelc.xcframework. sqlite3 needs no exclusion: on Apple +// platforms SQLite.swift imports the system `sqlite3` clang module, so its +// sqlite3_* references resolve at app link time from whatever the host links.) +const EXCLUDED_TARGETS = ['PirateLightClientKit', 'PirateDepsWrapper'] + +interface Platform { + archs: string[] + destination: string + dir: string +} + +// Arch baseline matches libpiratelc.xcframework: arm64 devices, +// arm64 + x86_64 simulators (so Intel Macs can still build). +const PLATFORMS: Platform[] = [ + { + archs: ['arm64'], + destination: 'generic/platform=iOS', + dir: 'ios-arm64' + }, + { + archs: ['arm64', 'x86_64'], + destination: 'generic/platform=iOS Simulator', + dir: 'ios-arm64-simulator' + } +] + +export function buildVendoredDeps(): void { + console.log('Building vendored SwiftPM dependency binary...') + rm(vendored) + mkdirSync(join(vendored, 'modules'), { recursive: true }) + mkdirSync(join(vendored, 'cmodules'), { recursive: true }) + + writeWrapperPackage() + + for (const platform of PLATFORMS) { + console.log(` Compiling deps for ${platform.dir}...`) + const dd = join(tmp, `deps-dd-${platform.dir}`) + // Always start from clean DerivedData: reusing it across SDK version bumps + // poisons the build with stale precompiled modules of the binary-target + // header, surfacing as bogus cannot-find-FFI-symbol errors. + rm(dd) + loud(wrapper, [ + 'xcodebuild', + '-scheme', + 'PirateDepsWrapper', + '-configuration', + 'Release', + '-destination', + platform.destination, + '-derivedDataPath', + dd, + // Honor the checked-in depsPackage.resolved; hard-fail on any version + // drift instead of silently re-resolving: + '-disableAutomaticPackageResolution', + `ARCHS=${platform.archs.join(' ')}`, + 'ONLY_ACTIVE_ARCH=NO', + 'BUILD_LIBRARY_FOR_DISTRIBUTION=NO', + 'SKIP_INSTALL=NO', + 'build' + ]) + + mergeDeps(dd, platform) + harvestModules(dd) + } + + // Package the per-platform archives as ONE xcframework: vendored_frameworks + // is a real link input (CocoaPods puts it on the app link line, unlike + // pod_target_xcconfig OTHER_LDFLAGS, which a static-framework pod's Libtool + // step silently ignores). The podspec only links it in PROVIDER mode. + console.log(' Creating libPirateDeps.xcframework...') + const xcframework = join(vendored, 'libPirateDeps.xcframework') + rm(xcframework) + const libArgs: string[] = [] + for (const platform of PLATFORMS) { + // CocoaPods requires a UNIFORM library basename across xcframework slices; + // stage each platform's lib under the same name in its own directory. The + // name also differs from react-native-zcash's libZcashDeps.a so that, if a + // future host ever links both archives, the -l flags don't clash: + const stage = join(tmp, `xcfw-${platform.dir}`) + rm(stage) + mkdirSync(stage, { recursive: true }) + cp( + join(vendored, `libPirateDeps-${platform.dir}.a`), + join(stage, 'libPirateDeps.a') + ) + libArgs.push('-library', join(stage, 'libPirateDeps.a')) + } + loud(tmp, [ + 'xcodebuild', + '-create-xcframework', + ...libArgs, + '-output', + xcframework + ]) + for (const platform of PLATFORMS) { + rm(join(vendored, `libPirateDeps-${platform.dir}.a`)) + } + + writeCompilerStamp() + assertHarvestComplete() + console.log('Vendored deps built.') +} + +// A throwaway SwiftPM package that depends on the SDK so SwiftPM builds the +// SDK's dependency graph; we then harvest those compiled deps. +function writeWrapperPackage(): void { + rm(wrapper) + mkdirSync(join(wrapper, 'Sources/PirateDepsWrapper'), { recursive: true }) + writeFileSync( + join(wrapper, 'Package.swift'), + `// swift-tools-version:5.9 +import PackageDescription +let package = Package( + name: "PirateDepsWrapper", + // Match the pod's floor (iOS 13) so the prebuilt deps import cleanly from + // any host at or above it (Edge develop pins 15.6): + platforms: [.iOS(.v13)], + products: [.library(name: "PirateDepsWrapper", type: .static, targets: ["PirateDepsWrapper"])], + dependencies: [.package(path: ${JSON.stringify(sdkClone)})], + targets: [.target(name: "PirateDepsWrapper", dependencies: [ + .product(name: "PirateLightClientKit", package: "PirateLightClientKit") + ])] +) +` + ) + writeFileSync( + join(wrapper, 'Sources/PirateDepsWrapper/Empty.swift'), + '@_exported import PirateLightClientKit\n' + ) + if (!existsSync(DEPS_RESOLVED)) { + throw new Error( + `Missing ${DEPS_RESOLVED} - the checked-in dependency pins. ` + + 'Regenerate by building the wrapper once without ' + + '-disableAutomaticPackageResolution and committing the resulting ' + + 'Package.resolved (keeping the shared packages at the versions ' + + 'react-native-zcash resolves).' + ) + } + cp(DEPS_RESOLVED, join(wrapper, 'Package.resolved')) +} + +// Merge every dependency target's compiled objects into one static lib per +// arch, then lipo the arches into the platform lib. Merging raw per-target +// objects (not the prelinked master objects) keeps every public symbol. +function mergeDeps(dd: string, platform: Platform): void { + const objectsRoot = join(dd, 'Build/Intermediates.noindex') + const archLibs: string[] = [] + + for (const arch of platform.archs) { + const objects = findObjects(objectsRoot, arch).filter(path => { + if (/IntegrationTests|Benchmarks|Tests\.build|Example/.test(path)) { + return false + } + return !EXCLUDED_TARGETS.some(target => + path.includes(`/${target}.build/`) + ) + }) + if (objects.length === 0) { + throw new Error( + `No ${arch} dependency objects found under ${objectsRoot}` + ) + } + const listFile = join(tmp, `deps-objects-${platform.dir}-${arch}.txt`) + writeFileSync(listFile, objects.join('\n')) + const archLib = join(tmp, `libPirateDeps-${platform.dir}-${arch}.a`) + rm(archLib) + loud(tmp, ['libtool', '-static', '-o', archLib, '-filelist', listFile]) + archLibs.push(archLib) + } + + const out = join(vendored, `libPirateDeps-${platform.dir}.a`) + rm(out) + if (archLibs.length === 1) { + cp(archLibs[0], out) + } else { + loud(tmp, ['lipo', '-create', ...archLibs, '-output', out]) + } +} + +function findObjects(base: string, arch: string): string[] { + const out: string[] = [] + const walk = (dir: string): void => { + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, entry.name) + if (entry.isDirectory()) walk(full) + else if ( + entry.name.endsWith('.o') && + dir.endsWith(`Objects-normal/${arch}`) + ) { + out.push(full) + } + } + } + walk(base) + return out +} + +// Copy the dep Swift `.swiftmodule`s (unioning arch slices across the +// per-platform builds) and the C modules (headers + module.modulemap) the SDK +// source imports. +function harvestModules(dd: string): void { + const products = findProductsDir(dd) + for (const entry of readdirSync(products)) { + if (!entry.endsWith('.swiftmodule')) continue + const name = entry.replace('.swiftmodule', '') + if (EXCLUDED_TARGETS.includes(name)) continue + const src = join(products, entry) + const dest = join(vendored, 'modules', entry) + if (statSync(src).isDirectory()) { + // Union the per-platform arch slices into one .swiftmodule bundle. + mkdirSync(dest, { recursive: true }) + cp(`${src}/.`, dest) + } else if (!existsSync(dest)) { + cp(src, dest) + } + } + // C modules: each compiled C target maps to a checkout include/ dir with a + // module.modulemap (synthesize a simple umbrella one if SwiftPM generated it). + const checkouts = join(dd, 'SourcePackages/checkouts') + if (!existsSync(checkouts)) return + for (const obj of readdirSync(products)) { + if (!obj.endsWith('.o')) continue + const mod = obj.replace('.o', '') + if (existsSync(join(vendored, 'cmodules', mod))) continue + const inc = findInclude(checkouts, mod) + if (inc == null) continue + const dest = join(vendored, 'cmodules', mod) + cp(inc, dest) + if (!existsSync(join(dest, 'module.modulemap'))) { + writeFileSync( + join(dest, 'module.modulemap'), + `module ${mod} {\n umbrella "."\n export *\n}\n` + ) + } + } +} + +function findProductsDir(dd: string): string { + const base = join(dd, 'Build/Products') + const entry = readdirSync(base).find(name => name.startsWith('Release-')) + if (entry == null) throw new Error(`No Products dir under ${base}`) + return join(base, entry) +} + +function findInclude(checkouts: string, mod: string): string | undefined { + for (const pkg of readdirSync(checkouts)) { + const inc = join(checkouts, pkg, 'Sources', mod, 'include') + if (existsSync(inc) && readdirSync(inc).some(f => f.endsWith('.h'))) { + return inc + } + } + return undefined +} + +// Record which Swift compiler produced the .swiftmodules (see the compiler +// coupling note in the file header). The podspec checks this at install time. +function writeCompilerStamp(): void { + const versionOutput = execFileSync('xcrun', ['swift', '--version'], { + encoding: 'utf8' + }) + const match = versionOutput.match(/swiftlang-[0-9.]+/) + if (match == null) { + throw new Error( + `Cannot parse Swift compiler version from: ${versionOutput}` + ) + } + writeFileSync(join(vendored, 'swift-version.txt'), `${match[0]}\n`) +} + +// Guard against a layout change in xcodebuild/SwiftPM silently producing an +// empty harvest (the build would only fail much later, in a consuming app). +function assertHarvestComplete(): void { + const moduleCount = readdirSync(join(vendored, 'modules')).filter(name => + name.endsWith('.swiftmodule') + ).length + const cmoduleCount = readdirSync(join(vendored, 'cmodules')).length + const xcframework = join(vendored, 'libPirateDeps.xcframework') + if (!existsSync(join(xcframework, 'Info.plist'))) { + throw new Error(`Missing or incomplete ${xcframework}`) + } + if (moduleCount < 10 || cmoduleCount < 5) { + throw new Error( + `Vendored module harvest looks incomplete: ${moduleCount} swiftmodules, ${cmoduleCount} cmodules` + ) + } +} + +function loud(cwd: string, argv: string[]): void { + execFileSync(argv[0], argv.slice(1), { + cwd, + stdio: 'inherit', + encoding: 'utf8' + }) +} diff --git a/scripts/depsPackage.resolved b/scripts/depsPackage.resolved new file mode 100644 index 0000000..e4fec63 --- /dev/null +++ b/scripts/depsPackage.resolved @@ -0,0 +1,202 @@ +{ + "pins": [ + { + "identity": "grpc-swift", + "kind": "remoteSourceControl", + "location": "https://github.com/grpc/grpc-swift.git", + "state": { + "revision": "956259f65a34c58dd76ae5df4511712e1087726b", + "version": "1.27.3" + } + }, + { + "identity": "pirate-light-client-ffi", + "kind": "remoteSourceControl", + "location": "https://github.com/piratenetwork/pirate-light-client-ffi.git", + "state": { + "revision": "b07e6fb619a8f0eadd344f4e0d3e81d8a7a0a33a" + } + }, + { + "identity": "sqlite.swift", + "kind": "remoteSourceControl", + "location": "https://github.com/stephencelis/SQLite.swift.git", + "state": { + "revision": "0c08856385fe24f7b76d8c51842d78a196e8e817", + "version": "0.15.5" + } + }, + { + "identity": "swift-algorithms", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-algorithms.git", + "state": { + "revision": "87e50f483c54e6efd60e885f7f5aa946cee68023", + "version": "1.2.1" + } + }, + { + "identity": "swift-asn1", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-asn1.git", + "state": { + "revision": "810496cf121e525d660cd0ea89a758740476b85f", + "version": "1.5.1" + } + }, + { + "identity": "swift-async-algorithms", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-async-algorithms.git", + "state": { + "revision": "9d349bcc328ac3c31ce40e746b5882742a0d1272", + "version": "1.1.3" + } + }, + { + "identity": "swift-atomics", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-atomics.git", + "state": { + "revision": "b601256eab081c0f92f059e12818ac1d4f178ff7", + "version": "1.3.0" + } + }, + { + "identity": "swift-certificates", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-certificates.git", + "state": { + "revision": "24ccdeeeed4dfaae7955fcac9dbf5489ed4f1a25", + "version": "1.18.0" + } + }, + { + "identity": "swift-collections", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-collections.git", + "state": { + "revision": "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e", + "version": "1.3.0" + } + }, + { + "identity": "swift-crypto", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-crypto.git", + "state": { + "revision": "6f70fa9eab24c1fd982af18c281c4525d05e3095", + "version": "4.2.0" + } + }, + { + "identity": "swift-http-structured-headers", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-http-structured-headers.git", + "state": { + "revision": "76d7627bd88b47bf5a0f8497dd244885960dde0b", + "version": "1.6.0" + } + }, + { + "identity": "swift-http-types", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-http-types.git", + "state": { + "revision": "45eb0224913ea070ec4fba17291b9e7ecf4749ca", + "version": "1.5.1" + } + }, + { + "identity": "swift-log", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-log.git", + "state": { + "revision": "bbd81b6725ae874c69e9b8c8804d462356b55523", + "version": "1.10.1" + } + }, + { + "identity": "swift-nio", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-nio.git", + "state": { + "revision": "e932d3c4d8f77433c8f7093b5ebcbf91463948a0", + "version": "2.95.0" + } + }, + { + "identity": "swift-nio-extras", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-nio-extras.git", + "state": { + "revision": "3df009d563dc9f21a5c85b33d8c2e34d2e4f8c3b", + "version": "1.32.1" + } + }, + { + "identity": "swift-nio-http2", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-nio-http2.git", + "state": { + "revision": "b6571f3db40799df5a7fc0e92c399aa71c883edd", + "version": "1.40.0" + } + }, + { + "identity": "swift-nio-ssl", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-nio-ssl.git", + "state": { + "revision": "173cc69a058623525a58ae6710e2f5727c663793", + "version": "2.36.0" + } + }, + { + "identity": "swift-nio-transport-services", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-nio-transport-services.git", + "state": { + "revision": "60c3e187154421171721c1a38e800b390680fb5d", + "version": "1.26.0" + } + }, + { + "identity": "swift-numerics", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-numerics.git", + "state": { + "revision": "0c0290ff6b24942dadb83a929ffaaa1481df04a2", + "version": "1.1.1" + } + }, + { + "identity": "swift-protobuf", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-protobuf.git", + "state": { + "revision": "5596511fce902e649c403cd4d6d5da1254f142b7", + "version": "1.35.1" + } + }, + { + "identity": "swift-service-lifecycle", + "kind": "remoteSourceControl", + "location": "https://github.com/swift-server/swift-service-lifecycle.git", + "state": { + "revision": "89888196dd79c61c50bca9a103d8114f32e1e598", + "version": "2.10.1" + } + }, + { + "identity": "swift-system", + "kind": "remoteSourceControl", + "location": "https://github.com/apple/swift-system.git", + "state": { + "revision": "7c6ad0fc39d0763e0b699210e4124afd5041c5df", + "version": "1.6.4" + } + } + ], + "version": 2 +} \ No newline at end of file diff --git a/scripts/updateSources.ts b/scripts/updateSources.ts index 56961d8..f8e37e4 100644 --- a/scripts/updateSources.ts +++ b/scripts/updateSources.ts @@ -8,6 +8,7 @@ import { deepList, justFiles, makeNodeDisklet, navigateDisklet } from 'disklet' import { existsSync, mkdirSync } from 'fs' import { join } from 'path' +import { buildVendoredDeps } from './buildVendoredDeps' import { copyCheckpoints } from './copyCheckpoints' const disklet = makeNodeDisklet(join(__dirname, '../')) @@ -19,6 +20,10 @@ async function main(): Promise { await rebuildXcframework() await copySwift() await copyCheckpoints(disklet) + // The SDK's SwiftPM deps (grpc-swift, SwiftNIO, SwiftProtobuf, SQLite.swift) + // are pre-built into a vendored static binary, pinned to the same versions + // as react-native-zcash's deps so the Edge app carries ONE grpc stack: + buildVendoredDeps() } function downloadSources(): void {