/ flake.nix
flake.nix
  1  # SPDX-FileCopyrightText: 2024 Mass Labs
  2  #
  3  # SPDX-License-Identifier: GPL-3.0-or-later
  4  {
  5    description = "Mass Market Contracts";
  6    inputs = {
  7      nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
  8      flake-parts = {
  9        url = "github:hercules-ci/flake-parts";
 10      };
 11      pre-commit-hooks = {
 12        url = "github:cachix/git-hooks.nix";
 13        inputs.nixpkgs.follows = "nixpkgs";
 14      };
 15      # services definitions
 16      process-compose-flake = {
 17        url = "github:Platonic-Systems/process-compose-flake";
 18      };
 19      flake-root.url = "github:srid/flake-root";
 20      services-flake.url = "github:juspay/services-flake";
 21      # solidity dependencies
 22      forge-std = {
 23        url = "github:foundry-rs/forge-std";
 24        flake = false;
 25      };
 26      openzeppelin = {
 27        url = "github:OpenZeppelin/openzeppelin-contracts";
 28        flake = false;
 29      };
 30      ds-test = {
 31        url = "github:dapphub/ds-test";
 32        flake = false;
 33      };
 34      solady = {
 35        url = "github:Vectorized/solady";
 36        flake = false;
 37      };
 38    };
 39  
 40    outputs = inputs @ {
 41      flake-parts,
 42      flake-root,
 43      forge-std,
 44      solady,
 45      openzeppelin,
 46      ds-test,
 47      systems,
 48      ...
 49    }:
 50      flake-parts.lib.mkFlake {inherit inputs;} {
 51        systems = import systems;
 52        imports = [
 53          inputs.pre-commit-hooks.flakeModule
 54          inputs.process-compose-flake.flakeModule
 55          inputs.flake-root.flakeModule
 56        ];
 57  
 58        flake = {
 59          processComposeModules.default = (import ./services.nix) {inherit inputs;};
 60        };
 61  
 62        perSystem = {
 63          pkgs,
 64          config,
 65          self',
 66          ...
 67        }: let
 68          buildInputs = with pkgs; [
 69            jq
 70            solc
 71            reuse
 72            foundry
 73          ];
 74          libs = pkgs.runCommand "contracts-libs" {} ''
 75            mkdir -p $out/libs
 76            ln -s ${forge-std} $out/libs/forge-std
 77            ln -s ${openzeppelin} $out/libs/openzeppelin
 78            ln -s ${ds-test} $out/libs/ds-test
 79            ln -s ${solady} $out/libs/solady
 80          '';
 81          src = pkgs.symlinkJoin {
 82            name = "deploy-contracts-src";
 83            paths = [./. libs];
 84          };
 85        in {
 86          process-compose = let
 87            cli = {
 88              options = {
 89                no-server = false;
 90                port = 8321;
 91              };
 92            };
 93            imports = [
 94              inputs.services-flake.processComposeModules.default
 95              inputs.self.processComposeModules.default
 96            ];
 97            services = {
 98              anvil.enable = true;
 99              deploy-contracts.enable = true;
100            };
101          in {
102            local-testnet = {
103              inherit imports services cli;
104            };
105          };
106  
107          pre-commit = {
108            check.enable = true;
109            settings = {
110              src = ./.;
111              hooks = {
112                alejandra.enable = true;
113                typos.enable = true;
114              };
115            };
116          };
117  
118          devShells.default = pkgs.mkShell {
119            inputsFrom = [config.flake-root.devShell]; # Provides $FLAKE_ROOT in dev shell
120            # local devshell scripts need to come first.
121            buildInputs =
122              buildInputs
123              ++ [
124                pkgs.typos-lsp # code spell checker
125                pkgs.nixd
126                self'.packages.deploy-market
127              ]
128              ++ config.pre-commit.settings.enabledPackages;
129  
130            shellHook = ''
131              ${config.pre-commit.settings.installationScript}
132              export FOUNDRY_SOLC_VERSION=${pkgs.solc}/bin/solc
133              # remove solidity cache (it not always notices branch changes)
134              test -d $FLAKE_ROOT/cache && rm -r $FLAKE_ROOT/cache
135              # check contents
136              rm $FLAKE_ROOT/libs
137              ln -s ${libs}/libs $FLAKE_ROOT/libs
138            '';
139          };
140          packages = rec {
141            default = mass-contracts;
142            deploy-market = pkgs.writeShellScriptBin "deploy-market" ''
143              tmp=$(mktemp -d)
144              export FOUNDRY_BROADCAST=$tmp/broadcast
145              export FOUNDRY_CACHE_PATH=$tmp/cache
146              export FOUNDRY_OUT=$tmp
147              export FOUNDRY_SOLC_VERSION=${pkgs.solc}/bin/solc
148              export FOUNDRY_ROOT=${src}
149              pushd $FOUNDRY_ROOT
150              ${pkgs.foundry}/bin/forge script ./script/deploy.s.sol:Deploy -s "deployContracts(bool, bool)" true false --broadcast --private-key $PRIVATE_KEY "$@"
151              popd
152            '';
153  
154            source-with-deps = pkgs.stdenv.mkDerivation {
155              name = "source-with-deps";
156              inherit src;
157            };
158  
159            mass-contracts = pkgs.stdenv.mkDerivation {
160              inherit buildInputs src;
161              name = "mass-contracts";
162  
163              dontPatch = true;
164              dontConfigure = true;
165              doCheck = true;
166  
167              buildPhase = ''
168                export FOUNDRY_SOLC_VERSION=${pkgs.solc}/bin/solc
169                forge script ./script/deploy.s.sol:Deploy -s "deployContracts(bool, bool)" true true
170              '';
171  
172              checkPhase = ''
173                forge test
174              '';
175  
176              installPhase = ''
177                mkdir -p $out/{bin,abi};
178                cp ./deploymentAddresses.json $out/deploymentAddresses.json
179                # create ABI files for codegen
180                for artifact in {ERC20,ShopReg,OrderPayments}; do
181                cd out/$artifact.sol/
182                for contract in *.json; do
183                  jq .abi $contract > $out/abi/$contract
184                done
185                cd ../../
186                done
187                jq .abi out/deploy.s.sol/EuroDollar.json > $out/abi/Eddies.json
188              '';
189            };
190          };
191        };
192      };
193  }