Documentation

Safe Guard

Safe Guard protects a Safe multisig wallet: a transaction runs only after your approvers approved it on their phones. Each phone reads the raw transaction itself, shows what it does (amounts, full addresses, risks) and signs with a key that only its Face ID or fingerprint unlocks. The Touchque guard on your Safe checks those signatures on chain and refuses a transaction without enough of them. Touchque never holds a key that can approve.

Off by default. An owner turns Safe Guard on in the dashboard under Organization → Features. Until the guard contract's external audit is finished, Safes can be added on test networks (Sepolia) only; the dashboard lists the networks where Touchque's guard is deployed.
Set it up

Dashboard → Developers → Safe Guard. The setup guide walks through these steps:

  1. Your Safe. A Safe you have (paste its address; Safe{Wallet}'s sep:0x… form works) or a new one made from the dashboard.
  2. Approvers and rules. The people who approve: members whose Touchque app has made a crypto key. How many approvals a transaction needs, and a higher number plus a waiting time for changes to the guard itself.
  3. Address book (optional). Names for the addresses you pay, kept on chain. With the address lock on, payments and allowances go only to the book; anything else is treated as a change to the guard (the higher number and the waiting time).
  4. Install the guard. The Safe's owners sign the setup calls and setGuard: from the dashboard with a browser wallet, by signing a proposal off chain, or by pasting the calls into Transaction Builder.
  5. Test approval (optional). A test transaction to an approver's phone, to see it decoded there.

Afterwards the page has four tabs: Safes (chain state, approvers, changes waiting on chain), Address book, Approvals (every request and its answer) and Policy (Touchque's own limits).

From your server

Your server sends the raw Safe transaction to an approver's phone, waits for the approval, checks it against its own transaction and the approver's key in the guard, and adds it to the signatures of execTransaction. The phone gets the raw fields only and decodes them itself, so a changed web page or server cannot change what it shows.

The other server SDKs have the same calls under their own naming: see the Safe Guard part of each SDK's README. type is an action type you defined (see Action types).
const { Touchque, verifySafeApproval, withSafeApprovals } = require('@touchque/node');
const tq = new Touchque(); // TQ_API_KEY / TQ_API_SECRET from the environment

// 1. Ask the approver's phone (always with biometrics)
const { requestId } = await tq.safeGuard.request({
  externalUsername: 'treasurer@acme.com',
  type: 'SAFE_PAYMENT',               // an action type you defined
  safeTx: {
    chainId: 11155111, safe: SAFE, guard: GUARD,
    tx: { to, value: '0', data, operation: 0, nonce: 42 },
    config: { threshold: 2, govThreshold: 3, govDelay: 172800, exitDelay: 259200 },
    batchTargets: [MULTI_SEND_CALL_ONLY],
    approverIndex: 0,                 // this person's index in the guard
  },
});

// 2. Wait for the phone (throws when refused or expired)
const status = await tq.safeGuard.waitForApproval({ requestId });

// 3. Check the approval yourself, against your own transaction and the approver's key in the guard: verifySafeApproval
// 4. Add the approvals to execTransaction's signatures: withSafeApprovals(ownerSignatures, approvals)