diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..a2d398f
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,8 @@
+# Path to your keystore file (JSON)
+KEYSTORE=/absolute/path/to/keystore.json
+
+# Password for your keystore
+PASSWORD=your_keystore_password
+
+# Optionally override the RPC URL (defaults set by network in deploy script)
+# RPC_URL=https://api.calibration.node.glif.io/rpc/v1
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b73142d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+.PHONY: build deploy-mupay deploy-multisig deploy-all clean chmod-deploy
+
+chmod-deploy:
+ chmod +x ./tools/deploy.sh
+
+build:
+ @echo "Building contracts..."
+ forge build
+ forge test
+
+deploy-mupay: chmod-deploy
+ @echo "Deploying MuPay contract..."
+ ./tools/deploy.sh mupay 314159
+
+deploy-multisig: chmod-deploy
+ @echo "Deploying Multisig contract..."
+ ./tools/deploy.sh multisig 314159
+
+deploy-all: deploy-mupay deploy-multisig
+
+clean:
+ forge clean
\ No newline at end of file
diff --git a/README.md b/README.md
index 522a8b2..03eb71f 100644
--- a/README.md
+++ b/README.md
@@ -17,3 +17,55 @@ The process flow of interactions between the client, server, and smart contract
This contract ensures secure, efficient, and trustless micro transactions for decentralized applications.
+
+## Local Development & Deployment
+
+### Prerequisites
+
+- [Foundry](https://book.getfoundry.sh/getting-started/installation) (`forge`, `cast`)
+- A valid Ethereum/FEVM keystore file and password
+- RPC endpoint (e.g. Filecoin Calibration, Mainnet, etc.)
+
+### Build and test
+
+```sh
+make build
+```
+
+## Deployment
+
+### Deploy MuPay contract
+
+```sh
+make deploy-mupay
+```
+
+### Deploy Multisig contract
+
+```sh
+make deploy-multisig
+```
+
+### Deploy both
+
+```sh
+make deploy-all
+```
+
+By default, deployment targets the Filecoin Calibration (calibnet) network (`chain_id: 314159`).
+You can adjust the `chain_id` or RPC endpoint in the Makefile or deployment script for other networks.
+
+## Environment Setup
+
+Copy `.env.example` to `.env` and fill in your values before deploying:
+```sh
+cp .env.example .env
+```
+
+Then edit `.env` as needed.
+
+You can generate a keystore file from a private key using:
+```sh
+cast wallet import --private-key $PRIVATE_KEY keystoreName
+# File will be saved to ~/.foundry/keystores/
+```
\ No newline at end of file
diff --git a/tools/deploy.sh b/tools/deploy.sh
new file mode 100755
index 0000000..703a568
--- /dev/null
+++ b/tools/deploy.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# deploy.sh - Deploys MuPay or Multisig contracts to a specified network
+# Usage: ./tools/deploy.sh
+# : mupay | multisig | both (default: both)
+# : 314159 (calibnet), 314 (mainnet), etc. (default: 314159)
+#
+# Example:
+# ./tools/deploy.sh mupay 314159
+# ./tools/deploy.sh multisig 314159
+# ./tools/deploy.sh both 314159
+
+set -euo pipefail
+
+CONTRACT="${1}"
+CHAIN_ID="${2:-314159}" # Default to calibnet
+
+if [ $# -lt 1 ]; then
+ echo "Usage: $0 [chain_id]"
+ exit 1
+fi
+
+# Load environment variables from .env if present
+if [ -f ".env" ]; then
+ export $(grep -v '^#' .env | xargs)
+fi
+
+# Set default RPC_URL if not set
+if [ -z "${RPC_URL:-}" ]; then
+ if [ "$CHAIN_ID" = "314159" ]; then
+ export RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
+ elif [ "$CHAIN_ID" = "314" ]; then
+ export RPC_URL="https://api.node.glif.io/rpc/v1"
+ else
+ echo "Error: RPC_URL must be set for CHAIN_ID $CHAIN_ID"
+ exit 1
+ fi
+fi
+
+if [ -z "${KEYSTORE:-}" ]; then
+ echo "Error: KEYSTORE is not set"
+ exit 1
+fi
+if [ -z "${PASSWORD:-}" ]; then
+ echo "Error: PASSWORD is not set"
+ exit 1
+fi
+
+ADDR=$(cast wallet address --keystore "$KEYSTORE" --password "$PASSWORD")
+echo "Deploying from address $ADDR to chain $CHAIN_ID"
+NONCE="$(cast nonce --rpc-url "$RPC_URL" "$ADDR")"
+
+deploy_contract() {
+ local contract_path="$1"
+ local contract_name="$2"
+
+ echo "Deploying $contract_name ($contract_path)"
+ DEPLOYED_ADDRESS=$(
+ forge create --rpc-url "$RPC_URL" \
+ --keystore "$KEYSTORE" \
+ --password "$PASSWORD" \
+ --broadcast \
+ --nonce $NONCE \
+ --chain-id $CHAIN_ID \
+ "$contract_path" \
+ | grep "Deployed to" | awk '{print $3}'
+ )
+
+ if [ -z "$DEPLOYED_ADDRESS" ]; then
+ echo "Error: Failed to extract $contract_name contract address"
+ exit 1
+ fi
+
+ echo "$contract_name deployed at: $DEPLOYED_ADDRESS"
+ NONCE=$((NONCE + 1)) # Increment nonce for next contract, if any
+}
+
+case "$CONTRACT" in
+ mupay)
+ deploy_contract "src/MuPay.sol:MuPay" "MuPay"
+ ;;
+ multisig)
+ deploy_contract "src/Multisig_2of2.sol:Multisig" "Multisig"
+ ;;
+ *)
+ echo "Invalid contract option: $CONTRACT"
+ echo "Usage: $0 [chain_id]"
+ exit 1
+ ;;
+esac
+echo "Deployment complete."
\ No newline at end of file