A complete Replit-based Rootstock Multisignature Wallet Demo showcasing secure transaction approvals and multi-party control on Rootstock (RSK) blockchain. This project demonstrates Rootstock's EVM compatibility through a fully functional multisig wallet with both smart contract and web interface.
- Overview
- Features
- Project Structure
- Quick Start
- Smart Contract
- Frontend
- Architecture
- Security Considerations
- Contributing
- License
RootSafe Multisig Wallet is a production-ready demonstration of a multisignature wallet on Rootstock blockchain. It consists of:
- Smart Contract - A secure, gas-optimized multisig wallet contract built with Foundry
- Frontend - A modern Next.js web application with TypeScript, wagmi, and Tailwind CSS
The wallet requires multiple owner approvals (M-of-N scheme) before executing transactions, providing enhanced security for managing RBTC and interacting with smart contracts.
graph TB
subgraph "Project Architecture"
Root[RootSafe Multisig Wallet]
subgraph "Smart Contract Layer"
Contract[MultiSigWallet.sol]
Tests[Foundry Tests]
Deploy[Deployment Script]
Contract --> Tests
Contract --> Deploy
end
subgraph "Frontend Layer"
NextJS[Next.js App]
Components[React Components]
Hooks[Wagmi Hooks]
Utils[Utility Functions]
NextJS --> Components
Components --> Hooks
Components --> Utils
end
subgraph "Blockchain Layer"
Rootstock[Rootstock Network]
RPC[RPC Node]
MetaMask[MetaMask Wallet]
end
subgraph "User Interface"
User[User Browser]
UI[Web Interface]
User --> UI
end
end
Root --> Contract
Root --> NextJS
Deploy --> Rootstock
Hooks --> MetaMask
MetaMask --> RPC
RPC --> Rootstock
UI --> NextJS
NextJS --> Hooks
Hooks --> Contract
Contract -.->|ABI| NextJS
style Root fill:#e1f5ff
style Contract fill:#fff3cd
style NextJS fill:#d4edda
style Rootstock fill:#f8d7da
style User fill:#d1ecf1
- ✅ Multi-owner support (configurable number of owners)
- ✅ Configurable required confirmations (M-of-N scheme)
- ✅ Transaction submission, confirmation, and execution
- ✅ Confirmation revocation (before execution)
- ✅ Multisig-controlled owner & threshold management (add/remove/replace owner, change requirement)
- ✅ Safe ETH/RBTC transfers using
call() - ✅ Reentrancy protection with OpenZeppelin's ReentrancyGuard
- ✅ Comprehensive event logging
- ✅ Gas-efficient design
- ✅ Foundry tests covering core flows and multisig-controlled owner/threshold management
- ✅ Modern Next.js 14 with App Router
- ✅ TypeScript for type safety
- ✅ Wagmi + Viem for blockchain interaction
- ✅ MetaMask wallet integration
- ✅ Real-time transaction updates (polling)
- ✅ Transaction filters and search
- ✅ Transaction details modal
- ✅ Owner management UI
- ✅ Wallet dashboard with charts
- ✅ Dark/light theme toggle
- ✅ Responsive design with Tailwind CSS
- ✅ Toast notifications
- ✅ Loading states and skeletons
RootSafe_Multisig_Wallet/
├── contracts/ # Smart contract project (Foundry)
│ ├── src/
│ │ └── MultiSigWallet.sol
│ ├── test/
│ │ └── MultiSigWallet.t.sol
│ ├── script/
│ │ └── DeployMultiSig.s.sol
│ ├── lib/
│ │ ├── openzeppelin-contracts/
│ │ └── forge-std/
│ ├── out/ # Compiled artifacts and ABIs
│ ├── foundry.toml
│ └── README.md
│
├── frontend/ # Frontend project (Next.js)
│ ├── src/
│ │ ├── app/ # Next.js app router
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ ├── providers.tsx
│ │ │ └── globals.css
│ │ ├── components/ # React components
│ │ │ ├── ConnectButton.tsx
│ │ │ ├── SubmitTxForm.tsx
│ │ │ ├── TxList.tsx
│ │ │ ├── TransactionItem.tsx
│ │ │ ├── OwnersList.tsx
│ │ │ ├── Navigation.tsx
│ │ │ ├── Footer.tsx
│ │ │ └── ...
│ │ ├── lib/ # Utilities
│ │ │ ├── contract.ts
│ │ │ └── utils.ts
│ │ └── abi/ # Contract ABIs
│ │ └── MultiSigWallet.json
│ ├── .env.local.example
│ ├── next.config.js
│ ├── tailwind.config.js
│ ├── package.json
│ └── README.md
│
└── README.md # This file
- Foundry (for smart contracts)
- Node.js 18+ (for frontend)
- MetaMask browser extension
- Rootstock Testnet RBTC (for deployment and gas)
git clone https://github.com/sainath5001/RootSafe_Multisig_Wallet.git
cd RootSafe_Multisig_Walletcd contracts
# Install dependencies
forge install
# Set up environment variables
cp .env.example .env
# Edit .env with your PRIVATE_KEY and ROOTSTOCK_TESTNET_RPC
# Run tests
forge test
# Deploy to Rootstock Testnet
# First, load environment variables from .env file
set -a && source .env && set +a
# IMPORTANT: configure the owners (comma-separated) and threshold
export OWNERS="0xOwner1,0xOwner2,0xOwner3"
export REQUIRED_CONFIRMATIONS=2
# Then deploy
forge script script/DeployMultiSig.s.sol:DeployMultiSig \
--fork-url $ROOTSTOCK_TESTNET_RPC \
--private-key $PRIVATE_KEY \
--broadcast --legacySave the deployed contract address for the frontend.
Before executing transactions from the frontend, send some RBTC to the multisig contract address (the contract balance must be >= the transaction Amount), otherwise executeTransaction will revert.
cd ../frontend
# Install dependencies
npm install
# After `forge build` in contracts/, sync the ABI into the frontend
npm run sync:abi
# Set up environment variables
cp .env.local.example .env.local
# Edit .env.local with your contract address and RPC URL
# Run development server
npm run devOpen http://localhost:3000 in your browser.
The smart contract is built with Foundry and implements a secure multisignature wallet. See contracts/README.md for detailed documentation.
Key Files:
contracts/src/MultiSigWallet.sol- Main contractcontracts/test/MultiSigWallet.t.sol- Test suitecontracts/script/DeployMultiSig.s.sol- Deployment script
Initial owners are set at deployment time (via OWNERS in the deploy script / environment). After deployment, the owner set and confirmation threshold can still be changed only through multisig-executed transactions (see addOwner, removeOwner, replaceOwner, and changeRequirement in MultiSigWallet.sol). Those functions use onlyWallet, so they must be executed as a transaction whose to is the wallet itself—no single owner can invoke them directly.
Example:
# Load environment variables from .env file
set -a && source .env && set +a
# Deploy with custom owners
OWNERS="0xYourAddress,0xOwner2,0xOwner3" \
REQUIRED_CONFIRMATIONS=2 \
forge script script/DeployMultiSig.s.sol:DeployMultiSig \
--fork-url $ROOTSTOCK_TESTNET_RPC \
--private-key $PRIVATE_KEY \
--broadcast --legacyTo check if you're an owner: Connect your wallet to the frontend - if you can submit transactions, you're an owner. See contracts/README.md for more details.
The frontend is built with Next.js 14, TypeScript, wagmi, and Tailwind CSS. See frontend/README.md for detailed documentation.
Key Features:
- Wallet connection via MetaMask
- Transaction submission and management
- Real-time updates
- Responsive design
- Dark/light theme
sequenceDiagram
participant U as User
participant F as Frontend
participant M as MetaMask
participant C as Contract
participant R as Rootstock
Note over U,R: Deployment Phase
U->>C: Deploy MultiSigWallet<br/>(with owners & required confirmations)
C->>R: Contract Deployed
R-->>C: Contract Address
Note over U,R: Transaction Flow
U->>F: Connect Wallet
F->>M: Request Connection
M-->>F: Wallet Connected
F->>C: Check if User is Owner
C-->>F: Owner Status
U->>F: Submit Transaction
F->>M: Sign Transaction
M->>C: submitTransaction()
C->>C: Store Transaction
C-->>F: Emit SubmitTransaction Event
U->>F: Approve Transaction
F->>M: Sign Transaction
M->>C: confirmTransaction()
C->>C: Update Confirmations
C-->>F: Emit ConfirmTransaction Event
alt Enough Confirmations
U->>F: Execute Transaction
F->>M: Sign Transaction
M->>C: executeTransaction()
C->>C: Check Confirmations
C->>R: Transfer RBTC
R-->>C: Success
C-->>F: Emit ExecuteTransaction Event
end
F->>C: Poll Transaction Data (every 8s)
C-->>F: Updated State
F->>F: Update UI
graph LR
subgraph "User Actions"
Connect[Connect Wallet]
Submit[Submit Transaction]
Approve[Approve Transaction]
Execute[Execute Transaction]
end
subgraph "Frontend Components"
ConnectBtn[ConnectButton]
SubmitForm[SubmitTxForm]
TxList[TxList]
TxItem[TransactionItem]
end
subgraph "Wagmi Hooks"
useAccount[useAccount]
useReadContract[useReadContract]
useWriteContract[useWriteContract]
useWaitForTransaction[useWaitForTransaction]
end
subgraph "Smart Contract"
submitTx[submitTransaction]
confirmTx[confirmTransaction]
executeTx[executeTransaction]
getTx[getTransaction]
end
Connect --> ConnectBtn
Submit --> SubmitForm
Approve --> TxItem
Execute --> TxItem
ConnectBtn --> useAccount
SubmitForm --> useWriteContract
TxList --> useReadContract
TxItem --> useWriteContract
useWriteContract --> submitTx
useWriteContract --> confirmTx
useWriteContract --> executeTx
useReadContract --> getTx
useWaitForTransaction --> TxItem
style Connect fill:#e1f5ff
style Submit fill:#d4edda
style Approve fill:#fff3cd
style Execute fill:#f8d7da
-
Smart Contract Security:
- Reentrancy protection with OpenZeppelin's ReentrancyGuard
- Safe ETH/RBTC transfers using
call() - Access control with
onlyOwnermodifier - Prevention of re-execution
- Comprehensive test coverage
-
Frontend Security:
- Always verify contract address before connecting
- Double-check transaction details before approving
- Use environment variables for sensitive data
- Never commit private keys or secrets
-
Best Practices:
- Audit smart contracts before mainnet deployment
- Use hardware wallets for owner keys
- Set appropriate confirmation thresholds
- Regularly review and update dependencies
cd contracts
forge test
forge test -vvv # Verbose output
forge test --gas-report # Gas reportingcd frontend
npm run dev # Development server
npm run build # Production build
npm run lint # Linting- Smart Contract Documentation - Detailed contract documentation with architecture diagrams
- Frontend Documentation - Frontend setup and usage guide
- Rootstock Documentation
- Rootstock Explorer (Testnet)
- Rootstock Explorer (Mainnet)
- Foundry Book
- Next.js Documentation
- Wagmi Documentation
- Viem Documentation
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
This software is provided "as is" without warranty. Use at your own risk. Always audit smart contracts before deploying to mainnet and handling real funds. This is a demonstration project for educational purposes.
Built with ❤️ for Rootstock (RSK)