# Multisig Transactions

:::warning
**Experimental.** Native multisig support is experimental and may change in a future release.
It is not yet available on Tempo mainnet or testnet.
:::

## Overview

Tempo supports **native multisig** accounts ([TIP-1061](https://docs.tempo.xyz/protocol/transactions)).
A multisig account is defined by a set of owners with voting weights and a threshold. A
transaction from the multisig is authorized when owner approvals collectively meet the
threshold.

With Viem, the flow is:

1. Derive the account with [`Account.fromMultisig`](/tempo/accounts/account.fromMultisig),
   passing the owners and threshold.
2. Prepare the transaction request, passing the multisig `account` (the config is inferred
   from it).
3. Each owner signs the prepared request to produce an **owner approval** signature.
4. Broadcast the transaction with the collected `signatures` (the prepared request already
   carries the multisig account as sender).

The first transaction from a multisig account **auto-bootstraps** (registers) it on-chain –
you don't need to pass an explicit `init` flag. Subsequent transactions are sent normally.

[See the Tempo Transactions specification](https://docs.tempo.xyz/protocol/transactions)

## Recipes

These recipes assume you have [set up a Tempo client](/tempo).

### Send a Multisig Transaction

:::code-group
```ts twoslash [example.ts]
import { Account } from 'viem/tempo'
import { client } from './viem.config'

const owner_1 = Account.fromSecp256k1(
  '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
)
const owner_2 = Account.fromSecp256k1(
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
)

// 1. Derive the multisig account (2-of-2) from its owners and threshold. // [!code focus]
const account = Account.fromMultisig({ // [!code focus]
  threshold: 2, // [!code focus]
  owners: [ // [!code focus]
    { owner: owner_1.address, weight: 1 }, // [!code focus]
    { owner: owner_2.address, weight: 1 }, // [!code focus]
  ], // [!code focus]
}) // [!code focus]

// 2. Prepare the request, passing the multisig account. // [!code focus]
const request = await client.prepareTransactionRequest({ // [!code focus]
  account, // [!code focus]
  calls: [ // [!code focus]
    { to: '0xcafebabecafebabecafebabecafebabecafebabe', value: 1n }, // [!code focus]
  ], // [!code focus]
}) // [!code focus]

// 3. Each owner approves the prepared request. Spread `...request` first so the // [!code focus]
//    explicit `account` wins (the owner signs over the multisig request). // [!code focus]
const signature_1 = await client.signTransaction({ ...request, account: owner_1 }) // [!code focus]
const signature_2 = await client.signTransaction({ ...request, account: owner_2 }) // [!code focus]

// 4. Broadcast with the collected signatures. The prepared `request` already // [!code focus]
//    carries the multisig account as sender, so it doesn't need re-passing. // [!code focus]
const hash = await client.sendTransaction({ // [!code focus]
  ...request, // [!code focus]
  signatures: [signature_1, signature_2], // [!code focus]
}) // [!code focus]
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```
:::

### M-of-N Approvals

A threshold below the owner count means only a subset of owners needs to approve. Below, a
2-of-3 multisig is satisfied by any two owners.

:::code-group
```ts twoslash [example.ts]
import { Account } from 'viem/tempo'
import { client } from './viem.config'

const owner_1 = Account.fromSecp256k1(
  '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
)
const owner_2 = Account.fromSecp256k1(
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
)
const owner_3 = Account.fromSecp256k1(
  '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
)

const account = Account.fromMultisig({
  threshold: 2, // [!code focus]
  owners: [
    { owner: owner_1.address, weight: 1 },
    { owner: owner_2.address, weight: 1 },
    { owner: owner_3.address, weight: 1 },
  ],
})

const request = await client.prepareTransactionRequest({
  account,
  calls: [
    { to: '0xcafebabecafebabecafebabecafebabecafebabe', value: 1n },
  ],
})

// Only 2 of the 3 owners need to approve to meet the threshold. // [!code focus]
const signature_1 = await client.signTransaction({ ...request, account: owner_1 }) // [!code focus]
const signature_3 = await client.signTransaction({ ...request, account: owner_3 }) // [!code focus]

const hash = await client.sendTransaction({
  ...request,
  signatures: [signature_1, signature_3], // [!code focus]
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```
:::

### Weighted Approvals

Owners can be assigned different weights. A single owner whose weight meets the threshold can
authorize alone.

:::code-group
```ts twoslash [example.ts]
import { Account } from 'viem/tempo'
import { client } from './viem.config'

const owner_1 = Account.fromSecp256k1(
  '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
)
const owner_2 = Account.fromSecp256k1(
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
)

const account = Account.fromMultisig({
  threshold: 2,
  owners: [
    { owner: owner_1.address, weight: 2 }, // [!code focus]
    { owner: owner_2.address, weight: 1 }, // [!code focus]
  ],
})

const request = await client.prepareTransactionRequest({
  account,
  calls: [
    { to: '0xcafebabecafebabecafebabecafebabecafebabe', value: 1n },
  ],
})

// The heavy owner alone satisfies the threshold (weight 2 >= 2). // [!code focus]
const signature = await client.signTransaction({ ...request, account: owner_1 }) // [!code focus]

const hash = await client.sendTransaction({
  ...request,
  signatures: [signature], // [!code focus]
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```
:::

## See More

<Cards>
  <Card icon="lucide:users" title="Account.fromMultisig" description="Instantiate a multisig account from a MultisigConfig." to="/tempo/accounts/account.fromMultisig" />

  <Card icon="lucide:layers" title="Batch Calls" description="Bundle multiple operations into a single atomic transaction." to="/tempo/guides/batch-calls" />

  <Card icon="lucide:book-open" title="Tempo Docs: Transactions" description="The full Tempo Transactions protocol specification." to="https://docs.tempo.xyz/protocol/transactions" />
</Cards>
