I am using the safe-core-sdk to propose transactions to the Gnosis Safe Transaction Service.

When the transaction has been proposed, I am then checking frequently via a job whether the transaction has been executed, and successful. I am doing this by using getTransaction, part of the safe-service-client, which returns some transaction object of type SafeMultisigTransactionResponse.

The issue I am having, is when I reject a transaction via the Safe UI, and then get the tx, there is no indication that the transaction has been rejected. The isExecuted property is false, and the isSuccessful property is still null. The safe tx hash in the UI for the on chain rejection, is also different to the safe tx hash for the proposed transaction.

Is there a way I can verify that a transaction has been rejected via the sdk?


1 Answer 1


It's actually impossible to reject a transaction in the Ethereum network. What happens under the hood when rejecting is that you create a transaction that uses the same nonce as the transaction you want to reject and 0 value and empty data. Once such transaction is executed, the Safe nonce is incremented and cannot be re-used anymore, making previous signatures useless (nonce is the part of transaction hash you sign).

To know if the transaction has been rejected, you can check that the Safe's nonce is greater than the transaction nonce and the isExecuted flag is false. To check if the transaction is being rejected or replaced you need to check if there is a pending transaction with the same nonce.

  • Ah okay that makes sense! Thanks. In this scenario, am I correct in saying, it's always (gnosis) safe to presume that the transaction with the nonce of the transaction we queued, will be the tx for the rejection?
    – jmulq
    Jan 24, 2022 at 14:27
  • Yes, but I think it's better to use the term "replacement" there because any transaction with the same nonce is not necessarily a rejection transaction by the Safe web app conventions: same nonce, 0 value, empty data, and safe address as a recipient.
    – mikheevm
    Jan 24, 2022 at 14:37
  • Is there any way to then get the associated rejection transaction via the core-sdk or safe service client? The only thing I can think of is by using getTransactions and passing the following options :{ executed: true }.. however there is no way to identify the nonce in the data thats returned.
    – jmulq
    Jan 24, 2022 at 14:39
  • 1. You can pass the nonce to the service client's getPendingTransactions method to get a list of pending transactions for a specific nonce 2. You have to define what "the associated rejection transaction" means for you and implement the logic yourself. Under the hood, it's not really a rejection but a replacement. The interface uses transactions same nonce, 0 value, empty data, and safe address as a recipient as a replacement transaction. They're displayed as rejections in the UI for UX purposes
    – mikheevm
    Jan 24, 2022 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.