Skip to content
Merged
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
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,55 @@ The process flow of interactions between the client, server, and smart contract
<img src="InteractionDiagram.png" alt="Hash Chain-Based Scheme" width="500"/>

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/
```
90 changes: 90 additions & 0 deletions tools/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash
# deploy.sh - Deploys MuPay or Multisig contracts to a specified network
# Usage: ./tools/deploy.sh <contract> <chain_id>
# <contract>: mupay | multisig | both (default: both)
# <chain_id>: 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 <mupay|multisig> [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 <mupay|multisig|both> [chain_id]"
exit 1
;;
esac
echo "Deployment complete."