diff --git a/.gitignore b/.gitignore
index 628e78f..d1ef770 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
# Datadir
*-data
+.DS_Store
diff --git a/USINGCODEX.md b/USINGCODEX.md
index b97be71..1ec6ce3 100644
--- a/USINGCODEX.md
+++ b/USINGCODEX.md
@@ -63,8 +63,9 @@ curl --request GET \
## Create storage availability
-**Warning**
-Are you currently in a Codex workshop?! Yes: Please skip this step.
+> #### 📢 **Warning**
+>Are you currently in a Codex workshop?! Yes: Please skip this step.
+>Proceed with 'Purchase storage'.
In order to start selling storage space to the network, you must configure your node with the following command. Once configured, the node will monitor on-chain requests-for-storage and will automatically enter into contracts that meet these specifications.
diff --git a/WORKSHOPSETUP.md b/WORKSHOPSETUP.md
index d889d5f..6d6cf51 100644
--- a/WORKSHOPSETUP.md
+++ b/WORKSHOPSETUP.md
@@ -1,40 +1,72 @@
# Workshop Setup
-With these instructions you can set up a Codex node on your machine, to use during the Brussels 2024 workshop. If you run into trouble and need help, ask a nearby Codexer!
+With these instructions you can set up a Codex node on your machine, to use during the workshop. If you run into trouble and need help, ask a nearby Codexer!
-## Clone this repository
+## 1. Clone this repository
```
git clone https://github.com/codex-storage/codex-testnet-starter.git
```
-## Local network
+## 2. Use the local network wifi
Switch to the workshop wifi:
- SSID: `codex`
- Password: `ethcc2024`
-Open a terminal in the scripts folder for your platform:
-- `scripts/linux`
-- `scripts/mac`
-- `scripts/windows`
+## 3. Open a terminal
+Open a terminal in the `/scripts` folder:
+```shell
+cd scripts
+chmod +x *.sh # make the scripts executable
+```
+> #### 📢 **Windows users**
+>If you are using a native Windows environment, and not a *nix-like environment
+>(eg CYGWIN/MINGW/MSYS/MINGW), use the `scripts/windows` directory.
-## Download Codex
-Run `download` script.
+## 4. Download Codex
+Run `download` script:
+```shell
+./download.sh
+```
-## Generate an Eth key-pair
-Run `generate` script.
+## 5. Generate an ETH key-pair
+Run `generate` script:
+```shell
+./generate.sh
-Keep the generated address at hand. Update the file named `eth.key` with your private key. You may need to change the permissions for this file. See the README.md in your platform specific folder.
+# Generating private key...
+# * your private key has been saved to /Users/egonat/repos/codex-storage/codex-testnet-starter/scripts/eth.key
+# * your ethereum address is 1b54dd8d3b45b419091821c7c47a36e014b8db79
+```
+> #### 📢 **Don't lose your generated address**
+>Take note of the generated address in the output so you can use it to mint
+tokens later.
-## Start Codex node
-Determine your local IP address. Use `ifconfig` or `ipconfig`, depending on your platform.
+## 6. Start Codex node
+Run the `run_client` script:
+```shell
+./run_client.sh
-Set local IP environment variable
- - Bash: `export LOCALIP="192.168.179.999"`
- - Batch: `set LOCALIP="192.168.179.999"`
+# LOCAL IP: 192.168.50.45
+# INF 2024-06-25 16:32:25.410+10:00 Creating a private key and saving it tid=25484256
+# INF 2024-06-25 16:32:25.414+10:00 Discovery SPR initialized topics="discv5"
+# ...
+```
-Run `run_client` script.
+> #### 📢 **Don't lose your generated address**
+>Check that your `LOCAL IP` in the output is correct, and if not, re-run the script with
+the LOCALfIP environment variable:
+> ```shell
+> LOCALIP=192.168.50.46 ./run_client.sh
+> ```
+>
-## Acquire tokens
-You can acquire tokens in one of two ways: Discord bot or faucet.
+
+## 7. Acquire tokens
+You can acquire tokens in one of two ways: the testnet faucets or the Discord bot.
+
+### Faucets
+You will need both ETH and TST to use Codex:
+ 1. Get some testnet ETH using https://faucet-eth.testnet.codex.storage.
+ 2. Get some testnet TST using https://faucet-tst.testnet.codex.storage.
### Discord bot
- Join the Codex discord server: https://discord.gg/codex-storage.
@@ -42,10 +74,6 @@ You can acquire tokens in one of two ways: Discord bot or faucet.
- Use `/set` command to enter your generated address.
- Use `/mint` command to receive some tokens.
-### Faucet
- - Follow instructions on https://faucet-eth.testnet.codex.storage to get some Eth.
- - Follow instructions on https://faucet-tst.testnet.codex.storage to get some test tokens.
-You will need both Eth and test tokens to use Codex.
-
-## Use Codex
-You can now proceed to use your Codex node. Follow the instructions [here](./USINGCODEX.md)
+## 8. Use Codex
+Setup complete! 🥳 You can now proceed to use your Codex node. Follow the
+[instructions](./USINGCODEX.md) 🐇
diff --git a/FORCODEXERS.md b/forcodexers/README.md
similarity index 90%
rename from FORCODEXERS.md
rename to forcodexers/README.md
index 62b75a2..f1ee385 100644
--- a/FORCODEXERS.md
+++ b/forcodexers/README.md
@@ -7,10 +7,11 @@ Notes for the Codex team members who will be running the workshop.
## Workshop Checklist
On-site, before the workshop starts:
- - [ ] Check Menti code and QT code in slides
+ - [ ] Check Menti code and QR code in slides
- [ ] Start local wifi network
- [ ] Check wifi credentials in slides
- [ ] Check internet access on wifi
- [ ] Start bootstrap node on NUC
+ - [ ] Start serve in /codex/v0.1.0
- [ ] Check bootstrap node SPR against SPR stored in workshop-bootstrapnode.info. If changed: UPDATE scripts in this repository quickly!
- [ ] Start host node on NUC
diff --git a/scripts/linux/download_prover.sh b/forcodexers/download_prover.sh
old mode 100755
new mode 100644
similarity index 100%
rename from scripts/linux/download_prover.sh
rename to forcodexers/download_prover.sh
diff --git a/scripts/linux/run_bootstrap.sh b/forcodexers/run_bootstrap.sh
old mode 100755
new mode 100644
similarity index 73%
rename from scripts/linux/run_bootstrap.sh
rename to forcodexers/run_bootstrap.sh
index 7eda7fa..de391ac
--- a/scripts/linux/run_bootstrap.sh
+++ b/forcodexers/run_bootstrap.sh
@@ -1,6 +1,8 @@
+# Start script for bootstrap node on local network NUC
+
./codex-v0.1.0-linux-amd64 \
--data-dir=data_bootstrap \
- --nat=${LOCALIP} \
+ --nat=192.168.88.253 \
--api-port=8078 \
--disc-port=8090 \
--listen-addrs=/ip4/0.0.0.0/tcp/8070 \
diff --git a/scripts/linux/run_host.sh b/forcodexers/run_host.sh
old mode 100755
new mode 100644
similarity index 91%
rename from scripts/linux/run_host.sh
rename to forcodexers/run_host.sh
index 379b5d0..4e466c2
--- a/scripts/linux/run_host.sh
+++ b/forcodexers/run_host.sh
@@ -1,3 +1,5 @@
+# Start script for storage node on local network NUC
+
BOOTSPR=$(curl http://localhost:8078/api/codex/v1/spr | cut -d '"' -f4)
# Quota = 11 GB
@@ -7,7 +9,7 @@ BOOTSPR=$(curl http://localhost:8078/api/codex/v1/spr | cut -d '"' -f4)
--data-dir=data_host \
--circuit-dir=circuit \
--storage-quota=11811160064 \
- --nat=${LOCALIP} \
+ --nat=192.168.88.253 \
--api-port=8180 \
--disc-port=8190 \
--listen-addrs=/ip4/0.0.0.0/tcp/8170 \
diff --git a/scripts/workshop-bootstrapnode.info b/forcodexers/workshop-bootstrapnode.info
similarity index 100%
rename from scripts/workshop-bootstrapnode.info
rename to forcodexers/workshop-bootstrapnode.info
diff --git a/scripts/download.sh b/scripts/download.sh
new file mode 100755
index 0000000..3ea4594
--- /dev/null
+++ b/scripts/download.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+
+source ./utils.sh
+
+# Function to extract archive file using native tools
+extract_archive() {
+ local archive_file="$1"
+ local extract_dir="$2"
+
+ case "$OS" in
+ linux|darwin)
+ # Use tar for Linux and macOS (assuming .tar.gz file)
+ tar -xzf "$archive_file" -C "$extract_dir"
+ ;;
+ windows)
+ # Use unzip for Windows
+ unzip -o "$archive_file" -d "$extract_dir"
+ ;;
+ *)
+ echo "Unsupported OS for archive extraction"
+ return 1
+ ;;
+ esac
+}
+
+# Function to download a file
+download_file() {
+ local url="$1"
+ local output_file="$2"
+
+ if command -v curl &> /dev/null; then
+ curl -L -o "$output_file" "$url"
+ elif command -v wget &> /dev/null; then
+ wget -O "$output_file" "$url"
+ else
+ echo "Error: Neither curl nor wget is available. Please install one of them."
+ return 1
+ fi
+}
+
+# Set variables
+OS=$(get_os)
+ARCH=$(get_arch)
+if [ "$OS" = "windows" ]; then
+ ARCHIVE_EXT=".zip"
+ EXE_EXT=".exe"
+else
+ ARCHIVE_EXT=".tar.gz"
+ EXE_EXT=""
+fi
+VERSION="v0.1.0"
+BASE_URL="https://github.com/codex-storage/nim-codex/releases/download/${VERSION}"
+EXTRACT_DIR="./"
+# Use BINARY_NAMES=("codex" "codex-prover") to also download/verify/extract prover binary
+BINARY_NAMES=("codex")
+
+# Download, verify, and extract each binary
+for BINARY_NAME in "${BINARY_NAMES[@]}"; do
+ FILE_NAME="${BINARY_NAME}-${VERSION}-${OS}-${ARCH}${ARCHIVE_EXT}"
+ DOWNLOAD_URL="${BASE_URL}/${FILE_NAME}"
+ CHECKSUM_URL="${BASE_URL}/${FILE_NAME}.sha256"
+
+ # Download the binary file
+ echo "Downloading ${FILE_NAME}..."
+ if ! download_file "$DOWNLOAD_URL" "$FILE_NAME"; then
+ echo "Download failed for ${FILE_NAME}"
+ exit 1
+ fi
+ echo
+
+ # Download the SHA256 checksum file
+ echo "Downloading SHA256 checksum for ${FILE_NAME}..."
+ if ! download_file "$CHECKSUM_URL" "${FILE_NAME}.sha256"; then
+ echo "Checksum download failed for ${FILE_NAME}"
+ exit 1
+ fi
+ echo
+
+ # Verify the checksum
+ echo "Verifying checksum for ${FILE_NAME}..."
+ EXPECTED_SHA256=$(cat "${FILE_NAME}.sha256" | cut -d' ' -f1)
+ if [ "$OS" = "darwin" ]; then
+ ACTUAL_SHA256=$(shasum -a 256 "$FILE_NAME" | cut -d ' ' -f 1)
+ else
+ ACTUAL_SHA256=$(sha256sum "$FILE_NAME" | cut -d ' ' -f 1)
+ fi
+
+ if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
+ echo "Checksum verification failed for ${FILE_NAME}. Expected: $EXPECTED_SHA256, Got: $ACTUAL_SHA256"
+ exit 1
+ fi
+ echo
+
+ # Extract the archive file
+ echo "Extracting ${FILE_NAME}..."
+ if ! extract_archive "$FILE_NAME" "$EXTRACT_DIR"; then
+ echo "Extraction failed for ${FILE_NAME}"
+ exit 1
+ fi
+
+ # Cleanup
+ rm ${FILE_NAME}
+ rm ${FILE_NAME}.sha256
+
+ # Change permissions to add execution (skipped for Windows)
+ FILE_NAME="${BINARY_NAME}-${VERSION}-${OS}-${ARCH}"
+ echo "Changing permissions for ${FILE_NAME}..."
+ BINARY_PATH="${EXTRACT_DIR}/${FILE_NAME}${EXE_EXT}"
+ if [ -f "$BINARY_PATH" ]; then
+ if ! change_permissions "$BINARY_PATH" +x; then
+ echo "Changing permissions failed for $BINARY_PATH"
+ exit 1
+ fi
+ else
+ echo "Warning: Binary $BINARY_PATH not found"
+ fi
+
+done
+
+echo "Setup completed successfully!"
diff --git a/scripts/generate.sh b/scripts/generate.sh
new file mode 100755
index 0000000..1593a1a
--- /dev/null
+++ b/scripts/generate.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -e
+
+echo "Generating private key..."
+
+response=$(curl -sX POST https://api.blockcypher.com/v1/eth/main/addrs)
+echo -n "${response}" | grep -o '"private":.*"' | cut -d'"' -f4 > ./eth.key
+address=$(echo -n "${response}" | grep -o '"address":.*"' | cut -d'"' -f4)
+chmod 600 ./eth.key
+
+echo " * your private key has been saved to ${PWD}/eth.key"
+echo " * your ethereum address is 0x${address}"
diff --git a/scripts/linux/README.md b/scripts/linux/README.md
deleted file mode 100644
index 9a2dd75..0000000
--- a/scripts/linux/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Permissions
-To fix the permissions of your eth.key file:
-`chmod 600 eth.key`
-
-# Additional requirements for prover
-`sudo apt-get install libzip-dev unzip`
diff --git a/scripts/linux/download.sh b/scripts/linux/download.sh
deleted file mode 100755
index a7ff854..0000000
--- a/scripts/linux/download.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-curl -o codex-v0.1.0-linux-amd64.tar.gz -L https://github.com/codex-storage/nim-codex/releases/download/v0.1.0/codex-v0.1.0-linux-amd64.tar.gz
-tar -xvzf codex-v0.1.0-linux-amd64.tar.gz
-
-chmod +x codex-v0.1.0-linux-amd64
-
-echo "Codex binary saved to ${PWD}/codex-v0.1.0-linux-amd64"
diff --git a/scripts/linux/eth.key b/scripts/linux/eth.key
deleted file mode 100644
index 10bc09c..0000000
--- a/scripts/linux/eth.key
+++ /dev/null
@@ -1 +0,0 @@
-PRIVATE KEY HERE
diff --git a/scripts/linux/generate.sh b/scripts/linux/generate.sh
deleted file mode 100755
index 8f41124..0000000
--- a/scripts/linux/generate.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-echo "Generating private key."
-
-response=$(curl -sX POST https://api.blockcypher.com/v1/eth/main/addrs)
-echo -n "${response}" | sed -n 's/^\s*"private": *"\(.*\)",$/\1/p' > ./eth.key
-address=$(echo -n "${response}" | sed -n 's/^\s*"address": *"\(.*\)"$/0x\1/p')
-chmod 600 ./eth.key
-
-echo " * your private key has been saved to ${PWD}/eth.key"
-echo " * your ethereum address is ${address}"
diff --git a/scripts/linux/run_client.sh b/scripts/linux/run_client.sh
deleted file mode 100755
index 855ed04..0000000
--- a/scripts/linux/run_client.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/env bash
-set -e
-
-if [ -z "$LOCALIP" ]; then
- echo "LOCALIP is not defined. Please set it to your IP address."
- exit 1
-fi
-
-if [ -z "$BOOTSPR" ]; then
- echo "BOOTSPR is not defined. Please set it to the bootstrap node SPR."
- exit 1
-fi
-
-if [ ! -f eth.key ]; then
- echo "eth.key does not exist. Please run generate.sh to create it."
- exit 1
-fi
-
-BOOTSPR=spr:CiUIAhIhA7dVYM0xcaXtsXiHmXWN1l2Irg_82sMFC6UochS0u7x2EgIDARo8CicAJQgCEiEDt1VgzTFxpe2xeIeZdY3WXYiuD_zawwULpShyFLS7vHYQ09LpswYaCwoJBMCoWP2RAh-aKkcwRQIhAK38tfXLaKKudMeJq9BEH-uMW0CxJ3lRdY0f1BfuKzZ9AiAwMLy5LijnR0qtne9KgVkjxCQWsqmv3meN9B5rd7yXSA
-
-./codex-v0.1.0-linux-amd64 \
- --data-dir=data_client \
- --storage-quota=11811160064 \
- --nat=${LOCALIP} \
- --api-port=8080 \
- --disc-port=8090 \
- --listen-addrs=/ip4/0.0.0.0/tcp/8070 \
- --bootstrap-node=${BOOTSPR} \
- persistence \
- --eth-private-key=eth.key \
- --eth-provider=https://rpc.testnet.codex.storage \
- --marketplace-address=0x9C88D67c7C745D2F0A4E411c18A6a22c15b37EaA
diff --git a/scripts/run_client.sh b/scripts/run_client.sh
new file mode 100755
index 0000000..0057334
--- /dev/null
+++ b/scripts/run_client.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+set -e
+
+source ./utils.sh
+
+if [ -z "$LOCALIP" ]; then
+ LOCALIP=$(get_ip)
+fi
+echo "LOCAL IP: ${LOCALIP}"
+
+if [ -z "$BOOTSPR" ]; then
+ # Local network SPR (on Ben's machine)
+ # BOOTSPR="spr:CiUIAhIhA7dVYM0xcaXtsXiHmXWN1l2Irg_82sMFC6UochS0u7x2EgIDARo8CicAJQgCEiEDt1VgzTFxpe2xeIeZdY3WXYiuD_zawwULpShyFLS7vHYQ09LpswYaCwoJBMCoWP2RAh-aKkcwRQIhAK38tfXLaKKudMeJq9BEH-uMW0CxJ3lRdY0f1BfuKzZ9AiAwMLy5LijnR0qtne9KgVkjxCQWsqmv3meN9B5rd7yXSA"
+ BOOTSPR="spr:CiUIAhIhAiJvIcA_ZwPZ9ugVKDbmqwhJZaig5zKyLiuaicRcCGqLEgIDARo8CicAJQgCEiECIm8hwD9nA9n26BUoNuarCEllqKDnMrIuK5qJxFwIaosQ3d6esAYaCwoJBJ_f8zKRAnU6KkYwRAIgM0MvWNJL296kJ9gWvfatfmVvT-A7O2s8Mxp8l9c8EW0CIC-h-H-jBVSgFjg3Eny2u33qF7BDnWFzo7fGfZ7_qc9P"
+ # echo "BOOTSPR is not defined. Please set it to the bootstrap node SPR."
+ # exit 1
+fi
+
+if [ ! -f eth.key ]; then
+ echo "eth.key does not exist. Please run generate.sh to create it."
+ exit 1
+fi
+
+# Set variables
+VERSION="v0.1.0"
+OS=$(get_os)
+ARCH=$(get_arch)
+DATA_DIR="data_client"
+
+mkdir -p ${DATA_DIR}
+chmod 0700 ${DATA_DIR}
+
+./codex-${VERSION}-${OS}-${ARCH} \
+ --data-dir=${DATA_DIR} \
+ --storage-quota=11811160064 \
+ --nat=${LOCALIP} \
+ --api-port=8080 \
+ --disc-port=8090 \
+ --listen-addrs=/ip4/0.0.0.0/tcp/8070 \
+ --bootstrap-node=${BOOTSPR} \
+ persistence \
+ --eth-private-key=eth.key \
+ --eth-provider=https://rpc.testnet.codex.storage \
+ --marketplace-address=0x9C88D67c7C745D2F0A4E411c18A6a22c15b37EaA
diff --git a/scripts/utils.sh b/scripts/utils.sh
new file mode 100755
index 0000000..92a84ef
--- /dev/null
+++ b/scripts/utils.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+# Function to detect OS
+get_os() {
+ case "$(uname -s)" in
+ Linux*) echo "linux";;
+ Darwin*) echo "darwin";;
+ CYGWIN*|MINGW*|MSYS*|MINGW*) echo "windows";;
+ *) echo "unknown";;
+ esac
+}
+
+# Function to detect CPU architecture
+get_arch() {
+ case "$(uname -m)" in
+ x86_64|amd64) echo "amd64";;
+ arm64|aarch64) echo "arm64";;
+ *) echo "Unsupported architecture: $(uname -m)"; exit 1;;
+ esac
+}
+
+# Function to change file permissions using native OS commands
+change_permissions() {
+ local file_path="$1"
+ local permissions="$2"
+
+ case "$OS" in
+ linux|darwin)
+ # Use chmod for Linux and macOS
+ chmod $permissions "$file_path"
+ ;;
+ windows)
+ # For Windows, we'll skip changing permissions
+ echo "Skipping permission change on Windows for $file_path"
+ ;;
+ *)
+ echo "Unsupported OS for changing permissions"
+ return 1
+ ;;
+ esac
+}
+
+# Function to get IP on Linux and macOS
+get_ip_unix() {
+ if command -v ip >/dev/null 2>&1; then
+ ip addr show | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d "/" -f 1 | head -n 1
+ elif command -v ifconfig >/dev/null 2>&1; then
+ ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | head -n 1
+ else
+ echo "Unable to find IP address. Neither 'ip' nor 'ifconfig' command found."
+ exit 1
+ fi
+}
+
+# Function to get IP on Windows
+get_ip_windows() {
+ ipconfig | grep -i "IPv4 Address" | awk '{print $NF}' | head -n 1
+}
+
+# Detect the operating system and call the appropriate function
+get_ip() {
+ case "$(uname -s)" in
+ Linux*|Darwin*)
+ echo $(get_ip_unix)
+ ;;
+ CYGWIN*|MINGW32*|MSYS*|MINGW*)
+ echo $(get_ip_windows)
+ ;;
+ *)
+ echo "Unsupported operating system"
+ exit 1
+ ;;
+ esac
+}
diff --git a/scripts/windows/README.md b/scripts/windows/README.md
deleted file mode 100644
index 2a208c9..0000000
--- a/scripts/windows/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Permissions
-To fix the permissions of your eth.key file in Windows:
- - Right-click 'eth.key' file
- - Properties
- - Security
- - Advanced
- - Add -> Select a principal -> Advanced -> Find now
- - Select you user from the list
- - OK -> OK
- - Check: "Full control", "Modify", "Read&exe", "Read", "Write"
- - OK
- - Disable inheritance -> Confirm warning
- - Apply and close
- - Apply and close
diff --git a/scripts/windows/download.bat b/scripts/windows/download.bat
index 1475912..a161d78 100644
--- a/scripts/windows/download.bat
+++ b/scripts/windows/download.bat
@@ -1,2 +1,69 @@
-curl -O -L https://github.com/codex-storage/nim-codex/releases/download/v0.1.0/codex-v0.1.0-windows-amd64.zip
-unzip codex-v0.1.0-windows-amd64.zip
+@echo off
+setlocal enabledelayedexpansion
+
+call utils.bat
+
+:: Set variables
+set "OS=windows"
+call :get_arch ARCH
+set "ARCHIVE_EXT=.zip"
+set "EXE_EXT=.exe"
+set "VERSION=v0.1.0"
+set "BASE_URL=https://github.com/codex-storage/nim-codex/releases/download/%VERSION%"
+set "EXTRACT_DIR=.\"
+set "BINARY_NAMES=codex"
+
+:: Download, verify, and extract each binary
+for %%B in (%BINARY_NAMES%) do (
+ set "FILE_NAME=%%B-%VERSION%-%OS%-%ARCH%%ARCHIVE_EXT%"
+ set "DOWNLOAD_URL=%BASE_URL%/!FILE_NAME!"
+ set "CHECKSUM_URL=%BASE_URL%/!FILE_NAME!.sha256"
+
+ echo Downloading !FILE_NAME!...
+ powershell -Command "& {Invoke-WebRequest -Uri '!DOWNLOAD_URL!' -OutFile '!FILE_NAME!'}"
+ if errorlevel 1 (
+ echo Download failed for !FILE_NAME!
+ exit /b 1
+ )
+
+ echo Downloading SHA256 checksum for !FILE_NAME!...
+ powershell -Command "& {Invoke-WebRequest -Uri '!CHECKSUM_URL!' -OutFile '!FILE_NAME!.sha256'}"
+ if errorlevel 1 (
+ echo Checksum download failed for !FILE_NAME!
+ exit /b 1
+ )
+
+ echo Verifying checksum for !FILE_NAME!...
+ for /f "tokens=1" %%a in (!FILE_NAME!.sha256) do set "EXPECTED_SHA256=%%a"
+ for /f "tokens=* usebackq" %%a in (`powershell -Command "& {Get-FileHash '!FILE_NAME!' -Algorithm SHA256 | Select-Object -ExpandProperty Hash}"`) do set "ACTUAL_SHA256=%%a"
+
+ if not "!ACTUAL_SHA256!"=="!EXPECTED_SHA256!" (
+ echo Checksum verification failed for !FILE_NAME!. Expected: !EXPECTED_SHA256!, Got: !ACTUAL_SHA256!
+ exit /b 1
+ )
+
+ echo Extracting !FILE_NAME!...
+ powershell -Command "& {Expand-Archive -Path '!FILE_NAME!' -DestinationPath '!EXTRACT_DIR!' -Force}"
+ if errorlevel 1 (
+ echo Extraction failed for !FILE_NAME!
+ exit /b 1
+ )
+
+ :: Cleanup
+ del !FILE_NAME!
+ del !FILE_NAME!.sha256
+)
+
+echo Setup completed successfully!
+exit /b 0
+
+:get_arch
+ set "arch_result=unknown"
+ for /f "tokens=2 delims=:" %%a in ('systeminfo ^| find "System Type"') do (
+ echo %%a | find "x64" > nul
+ if not errorlevel 1 set "arch_result=amd64"
+ echo %%a | find "ARM" > nul
+ if not errorlevel 1 set "arch_result=arm64"
+ )
+ set "%1=%arch_result%"
+exit /b
diff --git a/scripts/windows/download_prover.bat b/scripts/windows/download_prover.bat
deleted file mode 100644
index 7304d9c..0000000
--- a/scripts/windows/download_prover.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-curl -O -L https://github.com/codex-storage/nim-codex/releases/download/v0.1.0/codex-prover-v0.1.0-windows-amd64.exe.zip
-unzip codex-prover-v0.1.0-windows-amd64.exe.zip
diff --git a/scripts/windows/eth.key b/scripts/windows/eth.key
deleted file mode 100644
index 10bc09c..0000000
--- a/scripts/windows/eth.key
+++ /dev/null
@@ -1 +0,0 @@
-PRIVATE KEY HERE
diff --git a/scripts/windows/generate.bat b/scripts/windows/generate.bat
index 091d004..997f410 100644
--- a/scripts/windows/generate.bat
+++ b/scripts/windows/generate.bat
@@ -1 +1,13 @@
-curl -sX POST https://api.blockcypher.com/v1/eth/main/addrs
+@echo off
+setlocal enabledelayedexpansion
+
+echo Generating private key...
+
+:: Use PowerShell to make the API call and process the response
+powershell -Command "& { $response = Invoke-RestMethod -Uri 'https://api.blockcypher.com/v1/eth/main/addrs' -Method Post; $privateKey = $response.private; $address = $response.address; $privateKey | Out-File -FilePath '.\eth.key' -NoNewline; Write-Host ' * your private key has been saved to %cd%\eth.key'; Write-Host (' * your ethereum address is 0x' + $address); }"
+
+:: Set file permissions to read-only for the current user
+icacls .\eth.key /inheritance:r
+icacls .\eth.key /grant:r %USERNAME%:R
+
+exit /b 0
diff --git a/scripts/windows/run-client.bat b/scripts/windows/run-client.bat
new file mode 100644
index 0000000..2584b38
--- /dev/null
+++ b/scripts/windows/run-client.bat
@@ -0,0 +1,63 @@
+@echo off
+setlocal enabledelayedexpansion
+
+call utils.bat
+
+if not defined LOCALIP (
+ call :get_ip LOCALIP
+)
+echo LOCAL IP: %LOCALIP%
+
+if not defined BOOTSPR (
+ set "BOOTSPR=spr:CiUIAhIhAiJvIcA_ZwPZ9ugVKDbmqwhJZaig5zKyLiuaicRcCGqLEgIDARo8CicAJQgCEiECIm8hwD9nA9n26BUoNuarCEllqKDnMrIuK5qJxFwIaosQ3d6esAYaCwoJBJ_f8zKRAnU6KkYwRAIgM0MvWNJL296kJ9gWvfatfmVvT-A7O2s8Mxp8l9c8EW0CIC-h-H-jBVSgFjg3Eny2u33qF7BDnWFzo7fGfZ7_qc9P"
+)
+
+if not exist eth.key (
+ echo eth.key does not exist. Please run generate.bat to create it.
+ exit /b 1
+)
+
+:: Set variables
+set "VERSION=v0.1.0"
+set "OS=windows"
+call :get_arch ARCH
+set "DATA_DIR=data_client"
+
+if not exist %DATA_DIR% mkdir %DATA_DIR%
+icacls %DATA_DIR% /inheritance:r
+icacls %DATA_DIR% /grant:r %USERNAME%:(OI)(CI)F
+
+codex-%VERSION%-%OS%-%ARCH%.exe ^
+ --data-dir=%DATA_DIR% ^
+ --storage-quota=11811160064 ^
+ --nat=%LOCALIP% ^
+ --api-port=8080 ^
+ --disc-port=8090 ^
+ --listen-addrs=/ip4/0.0.0.0/tcp/8070 ^
+ --bootstrap-node=%BOOTSPR% ^
+ persistence ^
+ --eth-private-key=eth.key ^
+ --eth-provider=https://rpc.testnet.codex.storage ^
+ --marketplace-address=0x9C88D67c7C745D2F0A4E411c18A6a22c15b37EaA
+
+exit /b 0
+
+:get_arch
+ set "arch_result=unknown"
+ for /f "tokens=2 delims=:" %%a in ('systeminfo ^| find "System Type"') do (
+ echo %%a | find "x64" > nul
+ if not errorlevel 1 set "arch_result=amd64"
+ echo %%a | find "ARM" > nul
+ if not errorlevel 1 set "arch_result=arm64"
+ )
+ set "%1=%arch_result%"
+exit /b
+
+:get_ip
+ for /f "tokens=2 delims=:" %%a in ('ipconfig ^| findstr /c:"IPv4 Address"') do (
+ set "%1=%%a"
+ set "%1=!%1: =!"
+ goto :break
+ )
+ :break
+exit /b
diff --git a/scripts/windows/run_bootstrap.bat b/scripts/windows/run_bootstrap.bat
deleted file mode 100644
index 5eadaa8..0000000
--- a/scripts/windows/run_bootstrap.bat
+++ /dev/null
@@ -1,12 +0,0 @@
-start /b codex-v0.1.0-windows-amd64.exe ^
- --data-dir=data_bootstrap ^
- --nat=%LOCALIP% ^
- --api-port=8078 ^
- --disc-port=8090 ^
- --listen-addrs=/ip4/0.0.0.0/tcp/8070
-
-timeout 5
-
-cls
-
-curl http://localhost:8078/api/codex/v1/debug/info
diff --git a/scripts/windows/run_client.bat b/scripts/windows/run_client.bat
deleted file mode 100644
index e4391e4..0000000
--- a/scripts/windows/run_client.bat
+++ /dev/null
@@ -1,20 +0,0 @@
-set BOOTSPR="spr:CiUIAhIhA7dVYM0xcaXtsXiHmXWN1l2Irg_82sMFC6UochS0u7x2EgIDARo8CicAJQgCEiEDt1VgzTFxpe2xeIeZdY3WXYiuD_zawwULpShyFLS7vHYQ09LpswYaCwoJBMCoWP2RAh-aKkcwRQIhAK38tfXLaKKudMeJq9BEH-uMW0CxJ3lRdY0f1BfuKzZ9AiAwMLy5LijnR0qtne9KgVkjxCQWsqmv3meN9B5rd7yXSA"
-
-start /b codex-v0.1.0-windows-amd64.exe ^
- --data-dir=data_client ^
- --storage-quota=11811160064 ^
- --nat=%LOCALIP% ^
- --api-port=8080 ^
- --disc-port=8090 ^
- --listen-addrs=/ip4/0.0.0.0/tcp/8070 ^
- --bootstrap-node=%BOOTSPR% ^
- persistence ^
- --eth-private-key=eth.key ^
- --eth-provider=https://rpc.testnet.codex.storage ^
- --marketplace-address=0x9C88D67c7C745D2F0A4E411c18A6a22c15b37EaA
-
-timeout 5
-
-cls
-
-curl http://localhost:8080/api/codex/v1/debug/info
diff --git a/scripts/windows/run_host.bat b/scripts/windows/run_host.bat
deleted file mode 100644
index 509d69f..0000000
--- a/scripts/windows/run_host.bat
+++ /dev/null
@@ -1,29 +0,0 @@
-set BOOTSPR="spr:CiUIAhIhA7dVYM0xcaXtsXiHmXWN1l2Irg_82sMFC6UochS0u7x2EgIDARo8CicAJQgCEiEDt1VgzTFxpe2xeIeZdY3WXYiuD_zawwULpShyFLS7vHYQ09LpswYaCwoJBMCoWP2RAh-aKkcwRQIhAK38tfXLaKKudMeJq9BEH-uMW0CxJ3lRdY0f1BfuKzZ9AiAwMLy5LijnR0qtne9KgVkjxCQWsqmv3meN9B5rd7yXSA"
-
-@REM Quota = 11 GB
-@REM Availability = 10 GB
-
-start /b codex-v0.1.0-prover-windows-amd64.exe ^
- --data-dir=data_host ^
- --circuit-dir=circuit ^
- --storage-quota=11811160064 ^
- --nat=%LOCALIP% ^
- --api-port=8180 ^
- --disc-port=8190 ^
- --listen-addrs=/ip4/0.0.0.0/tcp/8170 ^
- --bootstrap-node=%BOOTSPR% ^
- persistence ^
- --eth-private-key=eth.key ^
- --eth-provider=https://rpc.testnet.codex.storage ^
- --marketplace-address=0x9C88D67c7C745D2F0A4E411c18A6a22c15b37EaA ^
- prover
-
-timeout 30
-
-cls
-
-curl http://localhost:8180/api/codex/v1/debug/info
-
-timeout 5
-
-curl --request POST --url http://localhost:8180/api/codex/v1/sales/availability --header "Content-Type: application/json" --data "{\"totalSize\": \"10737418240\", \"duration\": \"86400\", \"minPrice\": \"1\", \"maxCollateral\": \"9999999999\"}"
diff --git a/scripts/windows/utils.bat b/scripts/windows/utils.bat
new file mode 100644
index 0000000..e60b2e9
--- /dev/null
+++ b/scripts/windows/utils.bat
@@ -0,0 +1,29 @@
+@echo off
+
+:get_os
+ echo windows
+exit /b
+
+:get_arch
+ set "arch_result=unknown"
+ for /f "tokens=2 delims=:" %%a in ('systeminfo ^| find "System Type"') do (
+ echo %%a | find "x64" > nul
+ if not errorlevel 1 set "arch_result=amd64"
+ echo %%a | find "ARM" > nul
+ if not errorlevel 1 set "arch_result=arm64"
+ )
+ if "%arch_result%"=="unknown" (
+ echo Unsupported architecture: %PROCESSOR_ARCHITECTURE%
+ exit /b 1
+ )
+ set "%1=%arch_result%"
+exit /b
+
+:get_ip
+ for /f "tokens=2 delims=:" %%a in ('ipconfig ^| findstr /c:"IPv4 Address"') do (
+ set "%1=%%a"
+ set "%1=!%1: =!"
+ goto :break
+ )
+ :break
+exit /b