Onchain Daily Limit
The onchain daily limit feature allows partners to manage daily spending limits for Gnosis Pay Safe accounts.
All transactions are gasless, enabling users to perform these operations completely free of charge.
Overview
The onchain daily limit update process involves the following steps:
- Fetch Transaction Data - Get the transaction data for signing
- Sign and Submit - Sign the transaction and submit the update
- Monitor Update - Wait for the delay relay to process the change and check the new limit
- Transaction signing wallet must be one of the Gnosis Pay Safe signers
- Updates are processed after a 3-minute delay as transactions are going through the Gnosis Pay delay relay
Step 1: Fetch Transaction Data for Signing
Get the transaction data that needs to be signed by the user's wallet:
Endpoint:
GET /api/v1/accounts/onchain-daily-limit/transaction-data?onchainDailyLimit=${newLimit}
Parameters:
onchainDailyLimit
(required): The new daily limit value you want to set
Response:
{
"data": {
"transaction": {
"to": "0x...",
"value": 0,
"data": "0x..."
}
}
}
The transaction
object contains the data that needs to be signed by the user's wallet.
Step 2: Sign and Submit Transaction
Safe Activation Required: This step only works when the Gnosis Pay Safe account has been fully activated and its modules are deployed. If you receive an error during submission, ensure that the Safe account activation process has been completed first.
For more information about Safe account setup and module deployment, see the Safe Management API documentation.
2.1 Sign the Transaction
The transaction data from Step 1 must be signed by the user's wallet.
The wallet which is used to sign the transaction must be a signer of the Gnosis Pay Safe account.
2.2 Submit the Signed Transaction
Once signed, submit the transaction to update the daily limit:
Endpoint:
PUT /api/v1/accounts/onchain-daily-limit
Request Body:
{
"onchainDailyLimit": 1500,
"signature": "0x..."
}
Parameters:
onchainDailyLimit
(required): The new daily limit valuesignature
(required): The signed transaction data from Step 2.1
Response:
{
"data": {
"requestedOnchainDailyLimit": 1500
}
}
Step 3: Monitor the Update
The daily limit update is processed through a delay relay mechanism that executes after 3 minutes.
Poll the following endpoint to check when the new limit becomes active:
Endpoint:
GET /api/v1/accounts/onchain-daily-limit
Response:
{
"data": {
"onchainDailyLimit": 1500
}
}
Complete Implementation Example
The following example demonstrates the complete flow using the Gnosis Pay Account Kit library, which provides helper methods to simplify the transaction signing process:
import { populateExecuteEnqueue } from "@gnosispay/account-kit";
const safeAddress = "0x...";
const safeSignerAddress = "0x...";
const newOnchainDailyLimit = 1337;
/**
* Step 1: Fetch transaction data for signing
*/
const response = await fetch(
`https://api.gnosispay.com/api/v1/accounts/onchain-daily-limit/transaction-data?onchainDailyLimit=${newOnchainDailyLimit}`
);
const {
data: { transaction: transactionData },
} = await response.json();
/**
* Step 2: Sign and submit the transaction
*/
const { data: signature } = await populateExecuteEnqueue(
{ account: safeAddress, chainId: 100 },
transactionData,
(params) => {
return walletClient.signTypedData({
account: safeSignerAddress,
...params,
});
}
);
await fetch("https://api.gnosispay.com/api/v1/accounts/onchain-daily-limit", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
onchainDailyLimit: newOnchainDailyLimit,
signature,
}),
});
/**
* Step 3: Monitor for the updated limit
*/
const pollForUpdate = async () => {
const checkResponse = await fetch(
"https://api.gnosispay.com/api/v1/accounts/onchain-daily-limit"
);
const { data: { onchainDailyLimit: updatedLimit } } = await checkResponse.json();
if (updatedLimit === newOnchainDailyLimit) {
console.log(`Limit successfully updated to: ${updatedLimit}`);
return true;
}
console.log(`Waiting for update... Current: ${updatedLimit}, Target: ${newOnchainDailyLimit}`);
return false;
};
/**
* Poll every 30 seconds until the update is complete
*/
const interval = setInterval(async () => {
if (await pollForUpdate()) {
clearInterval(interval);
}
}, 30000);