From 9ede2f73e54ecd49db6a93592c4bdecd699ba35a Mon Sep 17 00:00:00 2001 From: Nero978 Date: Fri, 21 Aug 2026 19:54:57 +0800 Subject: [PATCH 1/4] fix: add DS_Store to gitignore --- .gitignore | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0295cc0..0e1bbc9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,9 @@ docs/ .env.* !.env.example -# anvil-data -anvil_state.json +# data +anvil-data/ +address-data/ + +# DS_Store files +.DS_Store From 5d43c13324502a8dbb25940e9cea50d3b17a05c7 Mon Sep 17 00:00:00 2001 From: Nero978 Date: Fri, 21 Aug 2026 19:56:18 +0800 Subject: [PATCH 2/4] feat: update Docker and Compose files to manage address data and permissions --- Dockerfile | 3 +++ docker-compose.prod.yml | 7 +++--- docker-compose.yml | 7 +++--- foundry.toml | 3 +++ script/Deploy.s.sol | 55 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4ec9257..e7563fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,9 @@ COPY --chown=foundry:foundry . . RUN git config --global --add safe.directory /app +# For data directory +RUN mkdir -p /app/address-data + RUN forge build RUN forge test \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 10ce582..21d3432 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -33,7 +33,7 @@ services: - "${ANVIL_PORT}:8545" volumes: - - anvil-data:/var/data + - ./anvil-data:/var/data healthcheck: test: @@ -71,5 +71,6 @@ services: - ${RPC_URL} - --broadcast -volumes: - anvil-data: \ No newline at end of file + volumes: + - ./broadcast:/app/broadcast + - ./address-data:/app/address-data \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e73a2eb..0b4fe8b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ services: - "${ANVIL_PORT}:${ANVIL_PORT}" volumes: - - anvil-data:/var/data + - ./anvil-data:/var/data healthcheck: test: @@ -72,5 +72,6 @@ services: - ${RPC_URL} - --broadcast -volumes: - anvil-data: \ No newline at end of file + volumes: + - ./broadcast:/app/broadcast + - ./address-data:/app/address-data diff --git a/foundry.toml b/foundry.toml index 25b918f..cad7d8c 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,5 +2,8 @@ src = "src" out = "out" libs = ["lib"] +fs_permissions = [ + { access = "read-write", path = "./address-data" } +] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 3983926..e4da243 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -13,7 +13,13 @@ import {LiquidityBuffer} from "../src/core/LiquidityBuffer.sol"; contract Deploy is Script { function run() external - returns (MockUSDC usdc, MockBond bond, Settlement settlement, Netting netting, LiquidityBuffer liquidityBuffer) + returns ( + MockUSDC usdc, + MockBond bond, + Settlement settlement, + Netting netting, + LiquidityBuffer liquidityBuffer + ) { // ========================================================= // Get deployer private key @@ -53,7 +59,12 @@ contract Deploy is Script { // 4. Deploy Netting // ========================================================= - netting = new Netting(deployer, address(usdc), address(bond), address(settlement)); + netting = new Netting( + deployer, + address(usdc), + address(bond), + address(settlement) + ); // ========================================================= // 5. Deploy LiquidityBuffer @@ -98,5 +109,45 @@ contract Deploy is Script { console2.log("NETTING:", address(netting)); console2.log("LIQUIDITY_BUFFER:", address(liquidityBuffer)); + + // ========================================================= + // Generate contract address file + // ========================================================= + + string memory filePath = "./address-data/addresses.json"; + + string memory json = vm.serializeAddress( + "addresses", + "NETTEDX_MOCK_USDC_CONTRACT_ADDRESS", + address(usdc) + ); + + json = vm.serializeAddress( + "addresses", + "NETTEDX_MOCK_BOND_CONTRACT_ADDRESS", + address(bond) + ); + + json = vm.serializeAddress( + "addresses", + "NETTEDX_SETTLEMENT_CONTRACT_ADDRESS", + address(settlement) + ); + + json = vm.serializeAddress( + "addresses", + "NETTEDX_NETTING_CONTRACT_ADDRESS", + address(netting) + ); + + json = vm.serializeAddress( + "addresses", + "NETTEDX_LIQUIDITY_BUFFER_CONTRACT_ADDRESS", + address(liquidityBuffer) + ); + + vm.writeJson(json, filePath); + + console2.log("Contract addresses written to:", filePath); } } From c1739cd6fa4abad580be6a7eedaaedb462412373 Mon Sep 17 00:00:00 2001 From: Nero978 Date: Fri, 21 Aug 2026 20:04:37 +0800 Subject: [PATCH 3/4] feat: add script to update backend .env with deployed contract addresses --- .github/workflows/Docker-Deploy.yml | 96 +++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/.github/workflows/Docker-Deploy.yml b/.github/workflows/Docker-Deploy.yml index 3c5e1e6..9493dd3 100644 --- a/.github/workflows/Docker-Deploy.yml +++ b/.github/workflows/Docker-Deploy.yml @@ -94,3 +94,99 @@ jobs: docker compose -f docker-compose.prod.yml up -d docker compose -f docker-compose.prod.yml ps + + # ========================================================= + # Update backend .env with deployed contract addresses + # ========================================================= + + ADDRESS_FILE="/opt/NettedX/NettedX-Blockchain/address-data/addresses.json" + ENV_FILE="/opt/NettedX/nettedx-back/.env" + + echo "Reading contract addresses from ${ADDRESS_FILE}" + + test -f "${ADDRESS_FILE}" + + python3 - "${ADDRESS_FILE}" "${ENV_FILE}" <<'PY' + import json + import os + import sys + import tempfile + + address_file = sys.argv[1] + env_file = sys.argv[2] + + with open(address_file, "r") as f: + addresses = json.load(f) + + keys = [ + "NETTEDX_MOCK_USDC_CONTRACT_ADDRESS", + "NETTEDX_MOCK_BOND_CONTRACT_ADDRESS", + "NETTEDX_SETTLEMENT_CONTRACT_ADDRESS", + "NETTEDX_NETTING_CONTRACT_ADDRESS", + "NETTEDX_LIQUIDITY_BUFFER_CONTRACT_ADDRESS", + ] + + # Validate all required addresses exist + for key in keys: + if key not in addresses: + raise RuntimeError( + f"Missing {key} in {address_file}" + ) + + if not addresses[key]: + raise RuntimeError( + f"Empty value for {key}" + ) + + with open(env_file, "r") as f: + lines = f.readlines() + + updated = set() + result = [] + + for line in lines: + stripped = line.lstrip() + + if "=" in line and not stripped.startswith("#"): + key = line.split("=", 1)[0] + + if key in addresses and key in keys: + result.append(f"{key}={addresses[key]}\n") + updated.add(key) + continue + + result.append(line) + + # Add missing keys + for key in keys: + if key not in updated: + result.append(f"{key}={addresses[key]}\n") + + # Atomic replacement of .env + directory = os.path.dirname(os.path.abspath(env_file)) + + fd, temp_file = tempfile.mkstemp( + dir=directory, + prefix=".env.", + text=True, + ) + + try: + with os.fdopen(fd, "w") as f: + f.writelines(result) + + os.replace(temp_file, env_file) + except Exception: + try: + os.unlink(temp_file) + except FileNotFoundError: + pass + raise + + print("Updated contract addresses:") + + for key in keys: + print(f"{key}={addresses[key]}") + PY + + echo "Backend .env updated successfully." \ No newline at end of file From 53cf812ea77f1b119b2261059541e8103d541d63 Mon Sep 17 00:00:00 2001 From: Nero978 Date: Fri, 21 Aug 2026 20:06:25 +0800 Subject: [PATCH 4/4] chore: format code --- script/Deploy.s.sol | 53 ++++++++++----------------------------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index e4da243..710d62e 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -13,13 +13,7 @@ import {LiquidityBuffer} from "../src/core/LiquidityBuffer.sol"; contract Deploy is Script { function run() external - returns ( - MockUSDC usdc, - MockBond bond, - Settlement settlement, - Netting netting, - LiquidityBuffer liquidityBuffer - ) + returns (MockUSDC usdc, MockBond bond, Settlement settlement, Netting netting, LiquidityBuffer liquidityBuffer) { // ========================================================= // Get deployer private key @@ -59,12 +53,7 @@ contract Deploy is Script { // 4. Deploy Netting // ========================================================= - netting = new Netting( - deployer, - address(usdc), - address(bond), - address(settlement) - ); + netting = new Netting(deployer, address(usdc), address(bond), address(settlement)); // ========================================================= // 5. Deploy LiquidityBuffer @@ -116,35 +105,15 @@ contract Deploy is Script { string memory filePath = "./address-data/addresses.json"; - string memory json = vm.serializeAddress( - "addresses", - "NETTEDX_MOCK_USDC_CONTRACT_ADDRESS", - address(usdc) - ); - - json = vm.serializeAddress( - "addresses", - "NETTEDX_MOCK_BOND_CONTRACT_ADDRESS", - address(bond) - ); - - json = vm.serializeAddress( - "addresses", - "NETTEDX_SETTLEMENT_CONTRACT_ADDRESS", - address(settlement) - ); - - json = vm.serializeAddress( - "addresses", - "NETTEDX_NETTING_CONTRACT_ADDRESS", - address(netting) - ); - - json = vm.serializeAddress( - "addresses", - "NETTEDX_LIQUIDITY_BUFFER_CONTRACT_ADDRESS", - address(liquidityBuffer) - ); + string memory json = vm.serializeAddress("addresses", "NETTEDX_MOCK_USDC_CONTRACT_ADDRESS", address(usdc)); + + json = vm.serializeAddress("addresses", "NETTEDX_MOCK_BOND_CONTRACT_ADDRESS", address(bond)); + + json = vm.serializeAddress("addresses", "NETTEDX_SETTLEMENT_CONTRACT_ADDRESS", address(settlement)); + + json = vm.serializeAddress("addresses", "NETTEDX_NETTING_CONTRACT_ADDRESS", address(netting)); + + json = vm.serializeAddress("addresses", "NETTEDX_LIQUIDITY_BUFFER_CONTRACT_ADDRESS", address(liquidityBuffer)); vm.writeJson(json, filePath);