> For a complete page index, fetch https://docs.conduit.xyz/llms.txt

# Deploy a Safe on Your Rollup

> How to deploy a Safe (multisig) wallet on your Conduit OP Stack rollup using the preinstalled Safe factory, via the Safe SDK or by calling the factory directly.

[Safe](https://safe.global) (formerly Gnosis Safe) is the standard multisig wallet used to control admin roles, treasuries, and contract ownership on Ethereum-style chains. Instead of one key controlling funds or permissions, a Safe requires a threshold of owners (e.g. "3 of 5") to approve any action.

> **Warning**
>
> This guide applies to **OP Stack** rollups only. The Safe factory is one of the OP Stack's [preinstalled contracts](/rollups/stacks/op-stack), deployed automatically at the same address on every chain. Arbitrum Orbit chains do not get this preinstall, so [contact Support](mailto:support@conduit.xyz) if you need a Safe deployed on an Orbit chain.

## Preinstalled contracts

Every OP Stack rollup launched on Conduit ships with these contracts already deployed, at the same addresses as Ethereum mainnet and other OP Stack chains:

| Contract                          | Address                                                                                     | Purpose                                                                                                      |
| --------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `SafeSingletonFactory`            | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7`                                                | Deterministic factory used to deploy the Safe singleton and proxy contracts                                  |
| `Safe`                            | `0x69f4D1788e39c87893C980c06EdF4b7f686e2938`                                                | Safe singleton logic contract (no events, cheaper gas)                                                       |
| `SafeL2`                          | `0xfb1bffC9d739B8D520DaF37dF666da4C687191EA`                                                | Safe singleton logic contract that emits events (recommended for L2s so activity is easier to index/monitor) |
| `MultiSend` / `MultiSendCallOnly` | `0x998739BFdAAdde7C933B942a68053933098f9EDa` / `0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B` | Batch multiple calls into a single Safe transaction                                                          |

For the full list and addresses, see the [Optimism preinstalls reference](https://specs.optimism.io/protocol/preinstalls.html#safe).

## Option 1: Deploy with the Safe SDK (recommended)

The [Safe `protocol-kit`](https://docs.safe.global/sdk/protocol-kit) handles building the deployment transaction for you: you just supply your RPC URL, owners, and threshold.

#### Install the SDK

```bash
npm install @safe-global/protocol-kit
```

#### Configure your Safe and predict its address

```typescript
import Safe, { PredictedSafeProps, SafeAccountConfig } from '@safe-global/protocol-kit'

const safeAccountConfig: SafeAccountConfig = {
  owners: ['0xOwner1...', '0xOwner2...', '0xOwner3...'],
  threshold: 2,
}

const predictedSafe: PredictedSafeProps = { safeAccountConfig }

const protocolKit = await Safe.init({
  provider: '[your_rpc_url]',
  signer: '[deployer_private_key]',
  predictedSafe,
})

const safeAddress = await protocolKit.getAddress()
```

#### Deploy the Safe

```typescript
const deploymentTransaction = await protocolKit.createSafeDeploymentTransaction()

const client = await protocolKit.getSafeProvider().getExternalSigner()
const txHash = await client.sendTransaction({
  to: deploymentTransaction.to,
  value: BigInt(deploymentTransaction.value),
  data: deploymentTransaction.data,
})
```

Once deployed, you can manage the Safe (propose/approve/execute transactions) using the [Safe `api-kit`](https://docs.safe.global/sdk/api-kit) against your own transaction service, or manually via `protocol-kit`, since the hosted Safe Wallet app does not support arbitrary custom chains out of the box.

## Option 2: Call the factory directly

If you'd rather not pull in the SDK, you can call the factory's `createProxyWithNonce` function yourself:

```solidity
function createProxyWithNonce(
    address _singleton,
    bytes memory initializer,
    uint256 saltNonce
) external returns (address proxy);
```

* `_singleton`: the `SafeL2` address above (or `Safe`, if you don't need events).
* `initializer`: the encoded call to `Safe.setup(owners, threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver)` (pass your `owners` array and `threshold`, and zero/empty values for the rest unless you need those features).
* `saltNonce`: any value you choose; it (plus your `initializer`) determines the resulting Safe's address, so you can predict it ahead of time.

This is lower-level and mainly useful if you're scripting deployments with Foundry/`cast` or integrating Safe creation into your own tooling.