Squads Protocol V4 multisig — ported to Arch Network (Satellite runtime), plus a web UI.
This repository contains a working port of the Squads Protocol V4 multisig program to the Arch Network / Satellite Anchor-style framework, and a Vite + React + TypeScript UI that drives it with real Bitcoin taproot wallets (Xverse / Unisat) on testnet.
arch-squads/
program/ # the Arch/Satellite cargo workspace (the ported on-chain program + built IDL)
ui/ # Vite + React + TS web app
This is a derivative work of Squads Protocol V4 and is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
- The original work is Squads Protocol V4 — https://github.com/Squads-Protocol/v4 — Copyright (C) Squads Protocol, licensed under AGPL-3.0.
- This repository is a modified port to Arch Network. The full license text is in
LICENSE; attribution and the list of separately-licensed files are inNOTICE. - Two files retain their upstream third-party licenses:
program/.../utils/system.rs(Anchor, Apache-2.0) andprogram/.../utils/small_vec.rs(borsh-rs, Apache-2.0 / MIT). SeeNOTICE.
This is an independent port. It is NOT affiliated with, sponsored by, or endorsed by Squads Protocol.
This is a testnet demo. The program has not been audited in its ported form. Do not use it with real funds. It is provided for evaluation and educational purposes only, with no warranty (see AGPL-3.0).
The port targets the Arch Network / Satellite runtime (arch-satellite-lang,
arch-satellite-apl, arch_program) instead of Solana + Anchor + anchor-spl. The
following changes were made versus upstream Squads V4 (all verifiable in program/):
- Custom global allocator removed. Upstream enabled a
custom-heapfeature and defined its own allocator; on Arch theentrypoint!macro already provides a global allocator, so thecustom-heapfeature and custom allocator were dropped (default = []in the programCargo.toml). - Address Lookup Tables are unsupported / rejected. Arch has no Address Lookup Table
program, so
executable_transaction_message.rsrequiresmessage.address_table_lookups.is_empty()and that no lookup-table account infos are passed; any message referencing ALT-loaded accounts is rejected. - Token program → APL.
anchor_spltoken/token_2022/token_interfaceusage was replaced witharch_satellite_apl::token(Token,TokenAccount,Mint,transfer_checked,TransferChecked). Token-2022 / Token Extensions are not supported on Arch. - Sysvars replaced with Arch syscalls.
Clock::get()→arch_program::program::get_clock();Rent::get()/ rent math →arch_program::rent::minimum_rent(...). The corresponding sysvar accounts were removed from the#[derive(Accounts)]structs. - Hashing.
solana_program::hash→arch_program::hashing_functions::sha256(e.g. the transaction-buffer hash check instate/transaction_buffer.rs). - Borsh packed length.
solana_program::borsh*::get_instance_packed_len(...)→borsh::to_vec(...).len()for computing serialized account sizes. - Pubkey bytes.
Pubkey::to_bytes()→Pubkey::serialize()where raw key bytes are needed (e.g. seed derivation,small_vec/ephemeral_signers). - Program id.
declare_id!is a 64-char hex secp256k1 Arch program id (60ecce…598e) rather than a base58 ed25519 Solana id. - INITIALIZER repointed. The one-time
program_config_initauthority constant was repointed from the upstream Squads key to a testnet key for this demo (a public key; no private key is included anywhere in this repo). - IDL
metadata.specnormalized to0.1.0in the built IDL.
The Memo program is also unavailable on Arch; memo-only "indexing" arguments from upstream are inert on this runtime.
| RPC | https://rpc.testnet.arch.network |
| Program id (hex) | 60ecce876888d47a7b6809e1e8ecc8e7afb11fd0aa741ea368a7128ffc18598e |
| Program id (base58) | 7XMaBUNuUYPwH9jSzJFTpvSWP1EHBNYf26NqJDUP7S6y |
| On-chain IDL account | 2c2806defae4443cd763ab7e6ba755c61ed75e29717fc2a88e40c18626e199c0 |
| Example multisig | EopNqeq52LrLGAvzUwFoh63AJ89bEMBzLx1ZWWb6vmWS |
| Explorer | https://explorer.arch.network (Testnet) |
Demo transactions:
program_config_init:9399b7c32146ff4d32e8ec17f7959ac806bfa3c8f33bdd084bd09a55dd9e12f5multisig_create_v2:1c33a8c6a240adb77f0c8a08e5e4b5363237c59936cbe688104b94021e4c3f69
The program builds to SBF with the pinned toolchain in
program/rust-toolchain.toml. program/Cargo.lock is
committed so the SBF build is reproducible.
cd program
# Build the SBF program (uses the pinned rust-toolchain)
cargo-build-sbf
# Deploy to Arch testnet with the Arch CLI (provide your own deployer key;
# Anchor.toml points its wallet at deploy-keys/deployer.json, which is gitignored)
arch-cli deploy \
--rpc https://rpc.testnet.arch.network \
target/deploy/squads_multisig_program.so
# Publish the IDL on-chain (the built IDL lives at target/idl/squads_multisig_program.json)
arch-cli idl publish target/idl/squads_multisig_program.json
target/is gitignored except for the checked-in IDL atprogram/target/idl/squads_multisig_program.json. You must supply your own deployer keypair — no keys are included in this repository.
cd ui
npm install
npm run dev # http://localhost:5173Connect an Xverse or Unisat browser wallet set to a Taproot (P2TR) address on Testnet4. Arch verifies a BIP-322 taproot key-path Schnorr signature against the BIP-86-tweaked output key; the Arch account key is the wallet's x-only (internal) pubkey.
The read-only multisig view works without a wallet. See ui/README.md
for the full UI architecture and signing details.
program/— the Arch/Satellite cargo workspace:Cargo.toml,Cargo.lock,rust-toolchain.toml,Anchor.toml,programs/squads_multisig_program/(the ported program source), and the built IDL attarget/idl/squads_multisig_program.json.ui/— the Vite + React + TS web app.