Owner Management
The owner's management feature allows you to list, add, and remove owners from Gnosis Pay Safe accounts. Owners are addresses that have the ability to sign transactions and manage the Safe account.
All transactions are gasless, enabling users to perform these operations completely free of charge.
Overview
The Safe owner management operations include:
- List Owners - Get the current list of owners
- Add Owner - Add a new owner
- Remove Owner - Remove an existing owner
For add/remove operations, the process involves:
- Fetch Transaction Data - Get the EIP-712 typed data for signing
- Sign and Submit - Sign the transaction and submit the operation
- Monitor Execution - Wait for the delay relay to process the operation
- Transaction signing wallet must be one of the current owners
- Add/Remove operations are processed after a 3-minute delay as transactions go through the Gnosis Pay delay relay
- Cards are temporarily frozen for 3 minutes during owner management operations as a security measure
- Cannot remove the last remaining owner from a Safe
Talking about Safe's owner is a misnomer. We are actually changing the owners of the Safe's module. But for the sake of simplicity, we will continue to refer to them as Safe owners.
List Safe Owners
Get the current list of addresses that are owners of the user's Safe account.
Endpoint:
GET /api/v1/owners
Response:
{
"data": {
"owners": [
"0x3270bf32AB647e90eF94A026c70Aa1daaaDA2382",
"0x456789ABcDEf123456789ABcdef123456789abc",
"0x123456789abcdef123456789abcdef123456789a"
]
}
}
The response contains an array of Ethereum addresses that are currently owners of the Safe.
Add Safe Owner
Step 1: Fetch Transaction Data for Adding Owner
Get the EIP-712 typed data that needs to be signed by the user's wallet:
Endpoint:
GET /api/v1/owners/add/transaction-data?newOwner=${newOwnerAddress}
Parameters:
newOwner
(required): The address to add as a new Safe owner (must be a valid 40-character hex address)
Response:
{
"data": {
"domain": {
"verifyingContract": "0x12345...",
"chainId": 100
},
"primaryType": "ModuleTx",
"types": {
"ModuleTx": [
{
"type": "bytes",
"name": "data"
},
{
"type": "bytes32",
"name": "salt"
}
]
},
"message": {
"data": "0x610...2382",
"salt": "0x1234567890...abcdef"
}
}
}
The response contains EIP-712 typed data that needs to be signed by the user's wallet.
Step 2: Sign and Submit Add Owner Transaction
2.1 Sign the Transaction
The typed data from Step 1 must be signed by the user's wallet using the EIP-712 standard.
The wallet which is used to sign the transaction must be a current owner of the Gnosis Pay Safe account.
2.2 Submit the Signed Transaction
Once signed, submit the transaction to add the new owner:
Endpoint:
POST /api/v1/owners
Request Body:
{
"newOwner": "0x3270b...382",
"signature": "0x1234567890abcdef...",
"message": {
"salt": "0x1234567890...abcdef",
"data": "0x610...2382"
}
}
Parameters:
newOwner
(required): The address to add as a new Safe ownersignature
(required): The EIP-712 signature from Step 2.1message
(required): The message object from the typed data response
Response:
{
"data": {
"id": "clp3j1f..6ezx2qv",
"safeAddress": "0x1234567...",
"transactionData": "{\"to\":\"0x123\",\"value\":\"0\",\"data\":\"0x610b5925...\"}",
"enqueueTaskId": "task_abc123",
"dispatchTaskId": null,
"readyAt": null,
"operationType": "CALL",
"userId": "user_123",
"status": "QUEUING",
"createdAt": "2025-02-07T12:34:56Z"
}
}
Remove Safe Owner
Step 1: Fetch Transaction Data for Removing Owner
Get the EIP-712 typed data that needs to be signed by the user's wallet:
Endpoint:
GET /api/v1/owners/remove/transaction-data?ownerToRemove=${ownerToRemoveAddress}
Parameters:
ownerToRemove
(required): The address to remove from Safe owners (must be a valid 40-character hex address)
Response:
{
"data": {
"domain": {
"verifyingContract": "0x12345...",
"chainId": 100
},
"primaryType": "ModuleTx",
"types": {
"ModuleTx": [
{
"type": "bytes",
"name": "data"
},
{
"type": "bytes32",
"name": "salt"
}
]
},
"message": {
"data": "0xe009cfde00000...ef123456789abc",
"salt": "0x1234567890...abcdef"
}
}
}
The response contains EIP-712 typed data that needs to be signed by the user's wallet.
Step 2: Sign and Submit Remove Owner Transaction
2.1 Sign the Transaction
The typed data from Step 1 must be signed by the user's wallet using the EIP-712 standard.
The wallet which is used to sign the transaction must be a current owner of the Gnosis Pay Safe account.
2.2 Submit the Signed Transaction
Once signed, submit the transaction to remove the owner:
Endpoint:
DELETE /api/v1/owners
Request Body:
{
"ownerToRemove": "0x45678...789abc",
"signature": "0x1234567890abcdef...",
"message": {
"salt": "0x1234567890...abcdef",
"data": "0xe009cfde000000...9abcdef123456789abc"
}
}
Parameters:
ownerToRemove
(required): The address to remove from Safe ownerssignature
(required): The EIP-712 signature from Step 2.1message
(required): The message object from the typed data response
Response:
{
"data": {
"id": "clp3j1f..6ezx2qv",
"safeAddress": "0x1234567...",
"transactionData": "{\"to\":\"0x123\",\"value\":\"0\",\"data\":\"0xe009cfde...\"}",
"enqueueTaskId": "task_abc123",
"dispatchTaskId": null,
"readyAt": null,
"operationType": "CALL",
"userId": "user_123",
"status": "QUEUING",
"createdAt": "2025-02-07T12:34:56Z"
}
}
Monitor Execution
Both add and remove owner operations are processed through a delay relay mechanism that executes after 3 minutes.
You can monitor the transaction status using the delay-relay monitoring endpoints or by checking your Safe's transaction history.
Complete Implementation Examples
Adding a Safe Owner
const newOwnerAddress = "0x3270b...382";
/**
* Step 1: Fetch transaction data for signing
*/
const response = await fetch(
`https://api.gnosispay.com/api/v1/owners/add/transaction-data?newOwner=${newOwnerAddress}`
);
const { data: typedData } = await response.json();
/**
* Step 2: Sign and submit the transaction
*/
const signature = await walletClient.signTypedData({
...typedData,
domain: {
...typedData.domain,
verifyingContract: typedData.domain.verifyingContract as `0x${string}`,
},
});
const submitResponse = await fetch("https://api.gnosispay.com/api/v1/owners", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
newOwner: newOwnerAddress,
signature,
message: typedData.message,
}),
});
const { data: transactionResult } = await submitResponse.json();
/**
* Step 3: Monitor execution (optional)
*/
console.log(`Add owner operation submitted with ID: ${transactionResult.id}`);
console.log(`Status: ${transactionResult.status}`);
console.log("Transaction will be processed after the 3-minute delay period");
Removing a Safe Owner
const ownerToRemoveAddress = "0x4567...89abc";
/**
* Step 1: Fetch transaction data for signing
*/
const response = await fetch(
`https://api.gnosispay.com/api/v1/owners/remove/transaction-data?ownerToRemove=${ownerToRemoveAddress}`
);
const { data: typedData } = await response.json();
/**
* Step 2: Sign and submit the transaction
*/
const signature = await walletClient.signTypedData({
...typedData,
domain: {
...typedData.domain,
verifyingContract: typedData.domain.verifyingContract as `0x${string}`,
},
});
const submitResponse = await fetch("https://api.gnosispay.com/api/v1/owners", {
method: "DELETE",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ownerToRemove: ownerToRemoveAddress,
signature,
message: typedData.message,
}),
});
const { data: transactionResult } = await submitResponse.json();
/**
* Step 3: Monitor execution (optional)
*/
console.log(`Remove owner operation submitted with ID: ${transactionResult.id}`);
console.log(`Status: ${transactionResult.status}`);
console.log("Transaction will be processed after the 3-minute delay period");
Listing Current Owners
/**
* Fetch current list of Safe owners
*/
const response = await fetch("https://api.gnosispay.com/api/v1/owners");
const { data } = await response.json();
console.log("Current Safe owners:", data.owners);
Security Considerations
- Ensure only trusted addresses are added as Safe owners
- Remember that owner changes cannot be reversed once executed after the delay period
- Cards are temporarily frozen during owner management operations as a security measure
- Cannot remove the last remaining owner from a Safe (this will result in an error)
- All current owners have equal authority to manage the Safe