# Start a Backup Proof

Prove that the user still holds an MPC wallet's backup share: the backup share and Aurea's cosigner sign a challenge of Aurea's together, and Aurea records when.

## Overview

- **What it proves.** An MPC wallet's three shares are the user's device, Aurea's cosigner and the user's backup. A backup proof is a signing ceremony whose only parties are the **backup** share and **Aurea's**: when it completes, the backup share worked. Run it with the share your app opens from the user's backup — their recovery file or passkey backup — and it proves that backup restores a working share.
- **When.** After a wallet is created, and whenever [Get the Backup State](https://docs.aureahub.com/docs/mpc-backup-get.md) answers `backupReconfirmDue` `true`: never proven, or last proven `reconfirmDays` days ago or more — 90 days, as the answer says. Read it when the wallet is opened and remind the user. **Nothing is ever refused because a proof is missing or old**: signing and recovery work as before.
- **The flow.** 1. Start: a challenge (ten minutes, used once) and its relay session. 2. Check the message and its digest (The Message). 3. Join the session as `BACKUP` and run the backup's side of an ordinary signature of `digest` with Aurea's cosigner (The Ceremony). 4. [Complete a Backup Proof](https://docs.aureahub.com/docs/mpc-backup-proof-complete.md) with the signature before `expiresAt`: the wallet's `backupPresent` becomes `true` and `backupConfirmedAt` now.
- **Who.** The wallet's owner, with an access token whose role runs MPC ceremonies (`owner`, `tenantadmin`, `signer`, `user`). Another user's wallet: `403` `MPC_WALLET_NOT_OWNED`.
- **A signature, like any other.** Starting a proof is a signing step: a frozen tenant, user, account or wallet is refused (`423`, [Freezes & Quarantines](https://docs.aureahub.com/docs/guide-freezes.md)). For an institutional tenant, its policy decides the proof as a `TYPED_MESSAGE` from the MPC wallet (source `mpc`) to an `internal` destination, and refuses it as it refuses any signature unless a rule names that type ([Policy Sets](https://docs.aureahub.com/docs/guide-policy-sets.md)).
- In your tenant's [audit trail](https://docs.aureahub.com/docs/audit-events.md) [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md): `mpc_wallet.backup_proof_started`, and `mpc_wallet.backup_confirmed` once completed, category `keys` — ids only, never the message, the digest or a signature.

## The Message

What the two shares sign is the hash of this text, exactly — one line each, `\n` between lines:

```text
Aurea Hub MPC backup proof
Signing this proves that the backup share of this wallet is held. It moves no funds and authorizes no transaction.

Version: 1
Wallet: 7c1e9b24-3f5a-4d8e-9b6c-1a2f3e4d5c6b
Address: 0x52908400098527886E0F7030069857D2E4169EE7
Curve: secp256k1
Tenant: 3f6a2c1e-8b4d-4e7a-9c5b-2d1e0f9a8b7c
User: 5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d
Challenge: 9b2f4e6a1c3d5e7f9a1b3c5d7e9f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9c1d3e5f
Issued at: 2026-10-14T09:12:40.000Z
Expires at: 2026-10-14T09:22:40.000Z
```

- `Wallet`, `Tenant` and `User`: ids, lower case. `Address`: the wallet's address. `Curve`: `secp256k1` or `ed25519`. `Challenge`: 32 random bytes, 64 hex characters. The two times in UTC, whole seconds, ten minutes apart.
- **The digest** (`digest`, `0x` and 64 hex characters): on `secp256k1`, the message's EIP-191 hash — what `personal_sign` signs, so any wallet library can check the proof (ethers' `hashMessage`); on `ed25519`, the SHA-256 of its UTF-8 bytes. An `ed25519` digest never starts with a zero byte.
- **Check before the backup share signs anything**: the lines are exactly these, `Wallet` is the wallet you asked for, `Address` its address, `Curve` its curve, and `digest` the hash of `message`. Never sign a digest you cannot read.

## The Ceremony

- The session's id is `bkp-` and a UUID; Aurea has asked its cosigner to join it as `AUREA`. Join it with [Relay: Join Session](https://docs.aureahub.com/docs/mpc-relay-join.md) as `moniker` `BACKUP` with `key` `"2"` — the backup party's role key from the wallet's key generation — then run the backup's side of an ordinary signature of `digest` with the signers `BACKUP` and `AUREA`, over the relay, as a recovery signature runs ([Start Signing Ceremony](https://docs.aureahub.com/docs/mpc-sign-start.md) › Committees). Read the signature as at any signing ceremony.
- **Only those two parties.** A backup proof's session takes the wallet owner's `BACKUP` with key `2` and Aurea's `AUREA`, never `DEVICE`. Any other join answers `403` `{ "error": "a backup proof's session takes the wallet owner's BACKUP party (role key 2) and the cosigner's AUREA party only" }`.
- **Why the device share cannot stand in.** A signature the device share makes with Aurea's elsewhere — an ordinary signing ceremony of the same digest — is a valid signature of the wallet, and proves nothing: what proves the backup is that Aurea's cosigner finished *this* session's signature with this session's two parties. Completing with such a signature answers `409` `BACKUP_PROOF_CEREMONY_FAILED` or `BACKUP_PROOF_PENDING`. Where Aurea enforces message rules for your tenant ([Signing Rules](https://docs.aureahub.com/docs/guide-signing-rules.md)), an ordinary signing ceremony of a backup proof's digest is refused: `403` `PERSONAL_SIGN_NOT_ALLOWED`.
- `wireVersion` picks the relay version as at [Start Signing Ceremony](https://docs.aureahub.com/docs/mpc-sign-start.md): `2` for any tenant, `1` only where your tenant may still use it.

## With the User's Approval

- A wallet whose signatures need its user's approval — an approval key bound to it at its key generation ([Start DKG Ceremony](https://docs.aureahub.com/docs/mpc-dkg-start.md) › An Approval Key) — carries the user's approval on its backup proof too, like on any other signature. Ask for the message first with [Prepare a Backup Proof](https://docs.aureahub.com/docs/mpc-backup-proof-prepare.md), check it as below (The Message), have the user approve its `digest` with the wallet's approval key, then start the proof with `prepared` and `approval` before the prepared message's `expiresAt`. The proof then signs that same message.
- Send both or neither: one without the other, a `prepared` made for another wallet or user, or an `approval` that is not one answers `422` `BACKUP_PROOF_PREPARED_INVALID`; a prepared message past its `expiresAt`, `410` `BACKUP_PROOF_EXPIRED` — prepare another.
- Without them the proof starts as above, with a challenge of its own — for a wallet without an approval key. A `secp256k1` wallet with one gets no backup proof without the user's approval: the cosigner does not join it.

## Endpoint

### `POST /v1/mpc/wallets/{walletId}/backup-proof/start`

Authentication: bearer token required.

Issues a backup proof's challenge and opens its BACKUP+AUREA relay session.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `walletId` | string (uuid) | yes | The MPC wallet's id (`walletId` from Register MPC Wallet) |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wireVersion` | integer | no | The relay version: `2`, or `1` where your tenant may still use it. The body may be `{}`. |
| `prepared` | string | no | [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md) The `prepared` token of Prepare a Backup Proof: the proof signs that message. Send it with `approval`, both or neither. |
| `approval` | object | no | [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md) The user's approval of the prepared `digest` with the wallet's approval key (Prepare a Backup Proof › The Approval). Send it with `prepared`. |

**Responses**

`200` OK

```json
{
  "challengeId": "2a7d9c41-6e3b-4f85-b0d2-8c1e5a9f3b67",
  "sessionId": "bkp-5e8b1d3a-0c7f-4a29-96e4-3b2d7f1c8a05",
  "committee": ["BACKUP", "AUREA"],
  "message": "Aurea Hub MPC backup proof\nSigning this proves that the backup share of this wallet is held. It moves no funds and authorizes no transaction.\n\nVersion: 1\nWallet: 7c1e9b24-3f5a-4d8e-9b6c-1a2f3e4d5c6b\nAddress: 0x52908400098527886E0F7030069857D2E4169EE7\nCurve: secp256k1\nTenant: 3f6a2c1e-8b4d-4e7a-9c5b-2d1e0f9a8b7c\nUser: 5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d\nChallenge: 9b2f4e6a1c3d5e7f9a1b3c5d7e9f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9c1d3e5f\nIssued at: 2026-10-14T09:12:40.000Z\nExpires at: 2026-10-14T09:22:40.000Z",
  "digest": "0x4f1c2a9e8b7d6c5f3e2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e",
  "expiresAt": "2026-10-14T09:22:40.000Z"
}
```

`403` Not yours

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "not your wallet",
  "details": { "code": "MPC_WALLET_NOT_OWNED" }
}
```

`429` Too many

```json
{
  "statusCode": 429,
  "error": "TooManyRequestsError",
  "message": "too many backup proofs: try again in a minute",
  "details": { "retryAfterSeconds": 60 }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/mpc/wallets/7c1e9b24-3f5a-4d8e-9b6c-1a2f3e4d5c6b/backup-proof/start \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "wireVersion": 2 }'
```

## Refusals

- `404` `MPC_WALLET_NOT_FOUND` (`mpc wallet not found`): no active MPC wallet with this id in your tenant. `403` `MPC_WALLET_NOT_OWNED` (`not your wallet`): another user's.
- `423`: the tenant, the user, an account holding the wallet or the wallet is frozen (`TENANT_FROZEN`, `USER_FROZEN`, `ACCOUNT_FROZEN`, `WALLET_FROZEN`), or a transfer the wallet received is quarantined (`OPERATION_QUARANTINED`); nothing is started.
- `409` `BACKUP_PROOF_TENANT_COSIGNER`: the wallet was made with your tenant's own co-signer, which holds its third share — Aurea's cosigner has none to prove the backup with.
- [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md) `422` `BACKUP_PROOF_PREPARED_INVALID` and `410` `BACKUP_PROOF_EXPIRED`: a prepared message and its approval that cannot be used (With the User's Approval).
- `409` `{ "error": "this tenant must use the version 2 MPC relay (send wireVersion: 2)" }`: as at Start Signing Ceremony.
- `429` `too many backup proofs: try again in a minute`, with `Retry-After: 60`: five starts at once, then one a minute, per user.
- For an institutional tenant, its policy's refusals at signing (`POLICY_*`, [Policy Sets](https://docs.aureahub.com/docs/guide-policy-sets.md) › Refusals at Signing).

## Implementation

```javascript
import { hashMessage, getAddress } from 'ethers';

// Prove the backup of a secp256k1 MPC wallet with the share opened from the user's backup
async function proveBackup(token, wallet, openBackupShare) {
  const api = (path, body) => fetch(`https://api.aureahub.com/v1/mpc${path}`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }).then(async (r) => { const b = await r.json(); if (!r.ok) throw b; return b; });

  const proof = await api(`/wallets/${wallet.walletId}/backup-proof/start`, { wireVersion: 2 });

  // Check before signing: this wallet, its address, and the digest of this message
  const lines = proof.message.split('\n');
  const field = (label) => lines.find((l) => l.startsWith(label + ': '))?.slice(label.length + 2);
  if (lines[0] !== 'Aurea Hub MPC backup proof'
      || field('Wallet') !== wallet.walletId
      || getAddress(field('Address')) !== getAddress(wallet.address)
      || field('Curve') !== 'secp256k1'
      || proof.digest !== hashMessage(proof.message)) {
    throw new Error('Not a backup proof of this wallet: do not sign');
  }

  // Join as BACKUP with key "2" and sign proof.digest with BACKUP + AUREA, over the relay,
  // with your MPC engine and the backup share (see Relay: Join Session)
  const backupShare = await openBackupShare();      // e.g. from the recovery file
  const signature = await runBackupSigning(proof.sessionId, proof.digest, backupShare);

  return api(`/wallets/${wallet.walletId}/backup-proof/complete`, {
    challengeId: proof.challengeId,
    signature,                                       // 0x r‖s‖v
  });
}
```

---

Web version: https://docs.aureahub.com/#mpc-backup-proof-start
