Skip to content

s3bc40/localsafe.eth

 
 

Repository files navigation

localsafe.eth

Disclaimer: Bear in mind this is still a project in early development. It still needs further testing and polishing. Feedback and contributions are welcome!

A 100% local web interface for managing multisignature wallets inspired by SafeWallet and EternalSafeWallet. No worrying about the SafeAPI being compromised... Run an instance yourself!

v0.2.0 - Now with IPFS deployment support and enhanced UI!

Features

  • Safe Account Dashboard: View Safe details, owners, threshold, nonce, and balance with enhanced UI organization.
  • Transaction Workflow: Create, import, export, and execute Safe transactions with improved collaboration tools.
  • WalletConnect Integration: Sign messages and transactions from dApps via WalletConnect v2.
  • IPFS Deployment: Automated deployment to IPFS via Pinata when creating GitHub releases.
  • SafeWallet Data Import/Export: Backup and restore address book, visited accounts, and undeployed safes.
  • Calldata Decoding: Decode transaction calldata directly in the UI for better transparency.
  • Collaboration Tools: Easy sharing of transactions, signatures, and links with organized dropdown menus.
  • Wallet Connection: MetaMask and RainbowKit integration with multiple wallet support.
  • Client-Side State: All wallet and Safe logic is handled client-side using wagmi, RainbowKit, and Safe Protocol Kit.
  • Hash-Based Routing: Uses React Router with hash-based routing for static IPFS deployment compatibility.

Quickstart

Requirements

  • Node.js v18+
  • pnpm
  • Anvil (for E2E tests)

Running the dev server

  1. Install pnpm.

  2. Clone the repository and install dependencies:

  git clone https://github.com/cyfrin/localsafe.eth
  cd localsafe.eth
  pnpm install
  1. Create a .env file in the root (take .env.example as a reference):
  NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id
  1. Start the development server:
  pnpm dev
  1. Open your browser and navigate to http://localhost:3000.

Running E2E Tests

Note: The testing infrastructure is currently in need of refactoring from Synpress. The existing tests may require updates to work with the latest changes.

Run localsafe.eth with Production Build

To run the app with a production build locally and run the optimized version:

  pnpm run localsafe

Deploying to IPFS

LocalSafe can be automatically deployed to IPFS via Pinata when you create a GitHub release or push a version tag. See DEPLOYMENT.md for complete setup instructions.

Quick Deploy:

# Create and push a version tag
git tag v0.2.0
git push origin v0.2.0

# Or create a GitHub Release via the UI

The deployment workflow will:

  1. Build the static site (pnpm run build)
  2. Deploy to IPFS via Pinata
  3. Output the IPFS CID and gateway URLs in the GitHub Actions logs

Access your deployment:

  • Pinata Gateway: https://gateway.pinata.cloud/ipfs/<CID>
  • IPFS Gateway: https://ipfs.io/ipfs/<CID>
  • Cloudflare IPFS Gateway: https://cloudflare-ipfs.com/ipfs/<CID>

Anvil State Management: --dump-state & --load-state

To ensure deterministic E2E tests, we use Anvil’s state management:

  • After setting up contracts and accounts, run:
    anvil --dump-state ./anvil-safe-state.json
    This creates a snapshot of the chain state in anvil-safe-state.json.
  • For all test runs, start Anvil with:
    anvil --load-state ./anvil-safe-state.json --block-time 1
    This restores the chain to the known state for reproducible tests.
  • The test runner script and package.json use this approach:
    "anvil": "anvil --load-state ./anvil-safe-state.json --block-time 1",
    "test:e2e": "bash tests/scripts/start-anvil-and-test.sh"

Developer Notes

  • Client-Side Architecture: All wallet and Safe logic is handled client-side for maximum privacy and flexibility.
  • Hash-Based Routing: Uses React Router with hash-based routing (HashRouter) to ensure compatibility with static IPFS deployments where server-side routing is not available.
  • Modular Structure: The project structure is modular, with reusable components and hooks for maintainability.
  • WalletConnect Integration: WalletConnect v2 is integrated for dApp connections and signing requests. Session data is persisted in localStorage.
  • Process Cleanup: Sometimes next-server and anvil processes may remain running in the background. Use pnpm run test:clean to kill them.
  • Local Contract Deployment: For deploying Safe contracts locally, see the instructions below.

Deploying Safe Contracts Locally with safe-smart-account

To run your own local Safe contracts for development, follow these steps:

  1. Clone the Repository
    git clone https://github.com/safe-global/safe-smart-account.git
    cd safe-smart-account
  2. Checkout the Correct Version
    git checkout tags/v1.4.1-3
  3. Install Dependencies and Build
    npm install
    npm run build
  4. Start a Local Anvil Node
    anvil
  5. Create a .env File
    MNEMONIC="test test test test test test test test test test test junk"
    NODE_URL="http://127.0.0.1:8545"
  6. Deploy Contracts
    npx hardhat --network custom deploy
  7. Update Contract Addresses
    • After deployment, copy the contract addresses from the output and update them in your project’s localContractNetworks.ts file.

Note: Currently, contract addresses are manually maintained in localContractNetworks.ts. In the future, we may automate this process or use environment variables for better flexibility.

TODO

  • Refactor E2E testing infrastructure from Synpress to support latest features.

  • Improve devcontainer setup for E2E tests; currently, UI mode has limitations.

  • Ensure smooth DX when switching between local and devcontainer environments and wild processes cleaning (next-server, anvil).

  • Adapt for different SafeWallet contract versions (currently optimized for 1.4.1-3).

  • Automate version value in DEFAULT_SAFE_WALLET_DATA constant (app/utils/constants.ts hardcoded to 3.0.0 now).

  • Add ENS name resolution for addresses in the UI.

  • Implement transaction history and filtering.

  • Extract out the EIP-712 data to it's own component for reusability.

  • Run linter

References

Contributors

Special thanks to all contributors!

About

A 100% local edition of the safe wallet

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 99.2%
  • Other 0.8%