Shared treasury. N-of-M trust.

A Gnosis-style multi-signature wallet written from scratch: nothing leaves the vault until enough owners confirm. Submit, confirm, execute — with failure-retry and full on-chain transparency.

Fund this vault:
Vault balance—
Signers—
Threshold—
Transactions—
You are—

Signers

loading…
📮

Propose a transaction

Owners propose outgoing operations — ETH transfers, token moves via calldata, or any call.

Transactions loading…

Loading transactions…

Live Activity (recent events from the chain)

EventDetailsBlockTx
Loading…
showing the latest 15 events

Understand this dApp (how to use it + the on-chain process)

🧭

How to use

The dApp drives the MultiSigWallet contract on the Sepolia testnet (2-of-3). Six steps, all from this page:

  1. Connect your wallet — press Connect Wallet (top-right) and make sure your wallet is on Sepolia; the chain badge shows the network.
  2. Fund the vault — type an amount in the Fund this vault box and press Deposit ETH; the ETH lands in the shared treasury.
  3. Propose a transaction — fill Destination, Value (ETH) and optional Calldata in Propose a transaction, then press Submit.
  4. Confirm or revoke — open the transaction in the Transactions list and press Confirm; press Revoke while it is still pending to undo your vote.
  5. Execute — once confirmations reach the threshold (2-of-3), any signer presses Execute and the funds or calldata call leave the vault.
  6. Tune & watch — signers can change the threshold in Wallet Settings, and Live Activity (↻ Refresh) streams every event from the chain.
⛓

The process — what happens on-chain

Every action on this page submits a signed transaction to the project's contracts:

  1. Pressing Deposit ETH sends value straight to the MultiSigWallet contract; its receive() fallback emits a Deposit event and the vault balance updates on-chain.
  2. Submit calls submitTransaction(destination, value, data) — MultiSigWallet appends a Transaction struct to its transactions array and emits Submission; the array index becomes your txId.
  3. Each Confirm calls confirmTransaction(txId) — MultiSigWallet sets confirmations[txId][owner] and increments confirmationCounts[txId], emitting Confirmation; Revoke calls revokeConfirmation(txId) to undo a pending confirmation.
  4. At the threshold, Execute calls executeTransaction(txId) — MultiSigWallet sets executed = true before the external call, while the inherited ReentrancyGuard contract's nonReentrant modifier blocks re-entrant re-execution.
  5. The call {value, data} runs on the destination: success emits Execution and the funds move; failure rolls the flag back, emits ExecutionFailure and keeps every confirmation so the transaction can be retried.
  6. Any signer can call changeThreshold(newThreshold) on MultiSigWallet — it reverts unless 1 ≤ threshold ≤ owners.length, then emits ThresholdChanged.
🕸

Flow graph

The lifecycle of every transaction on Sepolia — from deposit to release, left to right:

MultiSigWallet flow — deposit → submit → confirm → execute → funds released 1 · Deposit ETH MultiSigWallet · receive 2 · Submit transaction MultiSigWallet · submit 3 · Owners confirm MultiSigWallet · 2-of-3 4 · Execute call MultiSigWallet (guarded) 5 · Funds released MultiSigWallet events

If the external call fails, executed rolls back, ExecutionFailure is emitted and all confirmations are kept — press Execute again to retry.