| name | safe-multisig-on-abstract |
| description | Create and manage Safe multi-signature wallets on Abstract — deploy new Safes, configure owners and thresholds, propose and execute multi-sig transactions using the Safe SDK or the Safe UI. This skill should be used when working with Safe on Abstract, creating a multisig wallet on Abstract, safe.abs.xyz, Safe Protocol Kit on Abstract, multi-sig transactions, SafeL2, SafeProxyFactory, or managing shared wallets with multiple signers on Abstract. |
Safe Multisig on Abstract
Safe (formerly Gnosis Safe) is the standard multi-signature wallet on Abstract. Use it when multiple parties must approve transactions before execution — treasury management, team wallets, DAO operations, or any scenario requiring shared custody.
A Safe web interface is live at safe.abs.xyz.
Quick Start (Web UI)
For non-programmatic use, create and manage Safes directly at safe.abs.xyz. Connect a wallet, add owner addresses, set the confirmation threshold, and deploy.
Quick Start (SDK — Create a Safe)
npm install @safe-global/protocol-kit viem
import Safe, { SafeAccountConfig, PredictedSafeProps } from "@safe-global/protocol-kit";
import { abstract } from "viem/chains";
const safeAccountConfig: SafeAccountConfig = {
owners: [
"0xOwner1Address",
"0xOwner2Address",
"0xOwner3Address",
],
threshold: 2,
};
const predictedSafe: PredictedSafeProps = { safeAccountConfig };
const protocolKit = await Safe.init({
provider: abstract.rpcUrls.default.http[0],
signer: DEPLOYER_PRIVATE_KEY,
predictedSafe,
});
const safeAddress = await protocolKit.getAddress();
const deploymentTx = await protocolKit.createSafeDeploymentTransaction();
const client = await protocolKit.getSafeProvider().getExternalSigner();
const txHash = await client!.sendTransaction({
to: deploymentTx.to as `0x${string}`,
value: BigInt(deploymentTx.value),
data: deploymentTx.data as `0x${string}`,
chain: abstract,
});
After deployment, verify:
const kit = await protocolKit.connect({ safeAddress });
await kit.isSafeDeployed();
await kit.getOwners();
await kit.getThreshold();
Quick Start (SDK — Execute a Multi-sig Transaction)
import Safe from "@safe-global/protocol-kit";
import { MetaTransactionData, OperationType } from "@safe-global/types-kit";
const kitOwner1 = await Safe.init({
provider: "https://api.mainnet.abs.xyz",
signer: OWNER_1_PRIVATE_KEY,
safeAddress: SAFE_ADDRESS,
});
const txData: MetaTransactionData = {
to: "0xRecipientAddress",
value: "1000000000000000",
data: "0x",
operation: OperationType.Call,
};
const safeTx = await kitOwner1.createTransaction({ transactions: [txData] });
const signedTx = await kitOwner1.signTransaction(safeTx);
const kitOwner2 = await Safe.init({
provider: "https://api.mainnet.abs.xyz",
signer: OWNER_2_PRIVATE_KEY,
safeAddress: SAFE_ADDRESS,
});
const fullySignedTx = await kitOwner2.signTransaction(signedTx);
const executeTxResponse = await kitOwner1.executeTransaction(fullySignedTx);
Deployed Contracts
| Contract | Address (Mainnet & Testnet) |
|---|
| Safe | 0xC35F063962328aC65cED5D4c3fC5dEf8dec68dFa |
| SafeL2 | 0x610fcA2e0279Fa1F8C00c8c2F71dF522AD469380 |
| SafeProxyFactory | 0xc329D02fd8CB2fc13aa919005aF46320794a8629 |
| MultiSend | 0x309D0B190FeCCa8e1D5D8309a16F7e3CB133E885 |
For the full deployed contract list, see connecting-to-abstract skill → references/deployed-contracts.md.
Decision: UI vs SDK
| Scenario | Use |
|---|
| Manual treasury management | UI — safe.abs.xyz |
| Programmatic Safe creation | SDK — Protocol Kit |
| Automated multi-sig flows | SDK — Protocol Kit |
| Off-chain signature collection (proposal service) | UI — see Transaction Service caveat below |
| Batch transactions (multiple calls in one) | SDK — MultiSend via Protocol Kit |
Transaction Service Caveat
Abstract is not listed in Safe's official Transaction Service supported networks. The off-chain proposal flow (where owners sign asynchronously via the API Kit / SafeApiKit) may not work with the standard Safe infrastructure for Abstract.
Workarounds:
- Use safe.abs.xyz for off-chain signature collection (it runs its own backend)
- Use the Protocol Kit for fully onchain signing — pass the transaction object between signers in your own application
- For automated pipelines, coordinate signatures offchain (e.g., via a database or messaging) and submit the fully-signed transaction onchain
Gotchas
- Abstract is a ZK Stack chain — Safe contracts on Abstract are the same Safe codebase, but the underlying VM differs from standard EVM. The Protocol Kit handles this transparently.
- SafeL2 is the recommended singleton — on L2 chains, use the
SafeL2 contract (not Safe) for lower gas costs via event-based indexing
- Transaction Service ≠ Protocol Kit — the Protocol Kit works fully onchain and is chain-agnostic. The Transaction Service (API Kit) requires a supported backend endpoint.
- Gas sponsorship — Safe transactions on Abstract can be sponsored via a paymaster. See
abstract-global-wallet skill for paymaster patterns.
- Never store private keys in client code — use
cast wallet import, environment variables, or KMS for signer keys
Feature Reference
| Topic | Where to look |
|---|
| Protocol Kit detailed API | references/protocol-kit.md |
| Abstract network config (RPC, chain IDs) | connecting-to-abstract skill |
| All deployed contracts on Abstract | connecting-to-abstract skill → references/deployed-contracts.md |
| Safe official docs | docs.safe.global |
| Safe UI on Abstract | safe.abs.xyz |