Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
inputs.devshell.flakeModule
./flakeModules/default.nix
./flakeModules/ethereum-development/default.nix
./flakeModules/neutron-darwin.nix
./nixosModules/default.nix
./packages/default.nix
./tools/default.nix
Expand Down
12 changes: 12 additions & 0 deletions flakeModules/neutron-darwin.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Purpose: Override neutron package with Darwin support when on macOS
{ self, inputs, ... }:
{
perSystem = { pkgs, config, lib, system, ... }: {
# Override cosmos-nix neutron package with our Darwin-enabled version on macOS
_module.args = {
cosmos-nix-overrides = lib.optionalAttrs pkgs.stdenv.isDarwin {
neutron = config.packages.neutrond;
};
};
};
}
9 changes: 9 additions & 0 deletions packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
inherit (config.packages) sp1-rust;
};

# Neutron with Darwin support
neutron-darwin = (pkgs.callPackage ./neutron-darwin.nix {}).neutron;
libwasmvm = (pkgs.callPackage ./neutron-darwin.nix {}).libwasmvm;
neutrond = (pkgs.callPackage ./neutron-darwin.nix {}).neutrond;
Comment on lines +36 to +38

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The expression pkgs.callPackage ./neutron-darwin.nix {} is evaluated three separate times. This is inefficient and violates the DRY (Don't Repeat Yourself) principle. It would be better to evaluate it once, store the result in a let binding, and then reference the attributes from that variable.

For example, you could introduce a let binding in the parent scope:

# In the `let` block of the `perSystem` module
neutronPkgs = pkgs.callPackage ./neutron-darwin.nix {};

# Then in the `packages` attribute set
...
# Neutron with Darwin support
neutron-darwin = neutronPkgs.neutron;
libwasmvm = neutronPkgs.libwasmvm;
neutrond = neutronPkgs.neutrond;
...

Since a direct suggestion is constrained to the changed lines, I'm providing this as a broader refactoring suggestion.


# Solana packages from solana-tools.nix
inherit (solana-tools) solana-node anchor setup-solana nightly-rust anchor-wrapper solana-tools;
};
Expand All @@ -53,6 +58,9 @@
# Include our custom packages
config.packages.upload-contract

# Neutron with Darwin support
config.packages.neutron-darwin

# Solana development tools
config.packages.solana-tools

Expand All @@ -71,6 +79,7 @@
shellHook = ''
echo "Welcome to zero.nix development environment"
echo "Available packages: upload-contract, local-ic, sp1-rust, sp1"
echo "Neutron: neutrond (with macOS support via libwasmvm ${if pkgs.stdenv.isDarwin then "2.1.5" else "from cosmos-nix"})"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The version "2.1.5" is hardcoded in this shell hook message. This version is also defined in packages/neutron-darwin.nix. If the package version is updated in the future, this message will become outdated and misleading. To avoid this, you should reference the version dynamically from the libwasmvm package derivation.

echo "Neutron: neutrond (with macOS support via libwasmvm ${if pkgs.stdenv.isDarwin then config.packages.libwasmvm.version else \"from cosmos-nix\"})"

echo "Solana tools: solana-node, anchor, setup-solana, nightly-rust"
echo ""
echo "Run 'setup-solana' to initialize Solana development environment"
Expand Down
155 changes: 155 additions & 0 deletions packages/neutron-darwin.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{ lib
, stdenv
, fetchFromGitHub
, buildGoModule
, rustPlatform
, fetchurl

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fetchurl dependency is imported but not used in this file. It's good practice to remove unused dependencies to keep the code clean and avoid confusion.

, darwin
, libiconv
, writeShellScriptBin
, makeWrapper
}:

let
# Build libwasmvm for Darwin following the quartz approach
libwasmvm = rustPlatform.buildRustPackage rec {
pname = "libwasmvm";
version = "2.1.5";

src = fetchFromGitHub {
owner = "CosmWasm";
repo = "wasmvm";
rev = "v${version}";
hash = "sha256-qxrAYLUsVSLBZ1GqS5/Yq+K1ZCLqBSq3M0ws1mmWMqs=";
};

sourceRoot = "${src.name}/libwasmvm";

# Use the newer fetch method for git dependencies
useFetchCargoVendor = true;
cargoHash = "sha256-Q7Enw2pwZB7kzdf/tde/Q/dZhiDCUp19YWd2UY0Hq8w=";

nativeBuildInputs = lib.optionals stdenv.isDarwin [
darwin.cctools
];

buildInputs = lib.optionals stdenv.isDarwin [
darwin.apple_sdk.frameworks.Security
darwin.apple_sdk.frameworks.SystemConfiguration
libiconv
];

# Set macOS deployment target for compatibility
preBuild = lib.optionalString stdenv.isDarwin ''
export MACOSX_DEPLOYMENT_TARGET="11.0"
'';

postInstall = ''
cp target/${stdenv.hostPlatform.config}/release/libwasmvm.${if stdenv.isDarwin then "dylib" else "so"} $out/lib/
'';

doCheck = false;

meta = {
description = "WebAssembly VM for Cosmos chains";
homepage = "https://github.com/CosmWasm/wasmvm";
license = lib.licenses.asl20;
platforms = lib.platforms.unix;
};
};

# Build neutrond with Darwin support
neutrond = buildGoModule rec {
pname = "neutrond";
version = "6.0.3";

src = fetchFromGitHub {
owner = "neutron-org";
repo = "neutron";
rev = "v${version}";
hash = "sha256-kduM7WzJLGmw4Yg450UQZvv3s86jc3VXmion/CAdg+Y=";
};

vendorHash = "sha256-wJvvogrVr+rpdZkkHnqwwRlbbuTrlJhKwQ0e71eYXJc=";

# Enable CGO for libwasmvm
env.CGO_ENABLED = "1";

# Set build tags
tags = [ "netgo" ];

# Only build the main binary, not test packages
subPackages = [ "cmd/neutrond" ];

# Darwin-specific build inputs
nativeBuildInputs = [ makeWrapper ] ++ lib.optionals stdenv.isDarwin [
darwin.cctools
];

buildInputs = [ libwasmvm ] ++ lib.optionals stdenv.isDarwin [
darwin.apple_sdk.frameworks.Security
darwin.apple_sdk.frameworks.SystemConfiguration
darwin.apple_sdk.frameworks.CoreFoundation
darwin.apple_sdk.frameworks.CoreServices
libiconv
];

# Set environment variables for build
preBuild = ''
export CGO_CFLAGS="-I${libwasmvm}/include"
export CGO_LDFLAGS="-L${libwasmvm}/lib -lwasmvm"
${lib.optionalString stdenv.isDarwin ''
export MACOSX_DEPLOYMENT_TARGET="11.0"
''}
'';

# Fix dynamic library paths on Darwin
postInstall = lib.optionalString stdenv.isDarwin ''
install_name_tool -add_rpath ${libwasmvm}/lib $out/bin/neutrond
install_name_tool -change @rpath/libwasmvm.dylib ${libwasmvm}/lib/libwasmvm.dylib $out/bin/neutrond
'';

# Create wrapper with proper library paths
postFixup = ''
wrapProgram $out/bin/neutrond \
--prefix ${if stdenv.isDarwin then "DYLD_LIBRARY_PATH" else "LD_LIBRARY_PATH"} : "${libwasmvm}/lib"
'';

doCheck = false;

meta = {
description = "The most secure permissionless smart contract platform";
homepage = "https://neutron.org";
license = lib.licenses.asl20;
platforms = lib.platforms.unix;
};
};

# Create a smart wrapper following the quartz pattern
neutronWrapper = writeShellScriptBin "neutron" ''
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}

# First, try the Nix-built neutrond
if [ -x "${neutrond}/bin/neutrond" ]; then
export ${if stdenv.isDarwin then "DYLD_LIBRARY_PATH" else "LD_LIBRARY_PATH"}="${libwasmvm}/lib:''${${if stdenv.isDarwin then "DYLD_LIBRARY_PATH" else "LD_LIBRARY_PATH"}:+:''${${if stdenv.isDarwin then "DYLD_LIBRARY_PATH" else "LD_LIBRARY_PATH"}}}"
exec "${neutrond}/bin/neutrond" "$@"
Comment on lines +137 to +138

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This export command is redundant. The neutrond derivation is already wrapped using wrapProgram in the postFixup phase (lines 113-116), which correctly sets DYLD_LIBRARY_PATH or LD_LIBRARY_PATH. The wrapper generated by wrapProgram will be executed when "${neutrond}/bin/neutrond" is called, so this manual export is unnecessary and can be removed to simplify the script.

exec "${neutrond}/bin/neutrond" "$@"

# Fall back to system neutrond if available
elif command_exists neutrond; then
echo "Warning: Using system neutrond. Some features may not work as expected." >&2
exec neutrond "$@"
else
echo "Error: neutrond not found. Please install neutron or ensure it's in your PATH." >&2
exit 1
fi
'';

in
{
inherit libwasmvm neutrond neutronWrapper;

# Export the main wrapper as the default
neutron = neutronWrapper;
}
Loading