From 7068712e1c68c6575cb08ca1574e6e295c2db516 Mon Sep 17 00:00:00 2001 From: Jem <0x0xjem@gmail.com> Date: Tue, 18 Nov 2025 13:36:16 +0400 Subject: [PATCH 1/3] feat: adds support for signing using a custom nonce --- src/Safe.sol | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Safe.sol b/src/Safe.sol index 6264267..a259b91 100644 --- a/src/Safe.sol +++ b/src/Safe.sol @@ -390,15 +390,25 @@ library Safe { ); } + /// @notice Prepare the signature for a transaction, using a custom nonce + /// + /// @param self The Safe client + /// @param to The target address for the transaction + /// @param data The data payload for the transaction + /// @param operation The operation to perform + /// @param sender The address of the account that is signing the transaction + /// @param nonce The nonce of the transaction + /// @param derivationPath The derivation path for the transaction + /// @return signature The signature for the transaction function sign( Client storage self, address to, bytes memory data, Enum.Operation operation, address sender, + uint256 nonce, string memory derivationPath ) internal returns (bytes memory) { - uint256 nonce = getNonce(self); if (bytes(derivationPath).length > 0) { string[] memory inputs = new string[](8); inputs[0] = "cast"; @@ -431,4 +441,16 @@ library Safe { return abi.encodePacked(sig.r, sig.s, sig.v); } } + + /// @notice Prepare the signature for a transaction, using the nonce from the Safe + function sign( + Client storage self, + address to, + bytes memory data, + Enum.Operation operation, + address sender, + string memory derivationPath + ) internal returns (bytes memory) { + return sign(self, to, data, operation, sender, getNonce(self), derivationPath); + } } From 4de631d559eade179b149aef610aaebe5a1d8f46 Mon Sep 17 00:00:00 2001 From: Jem <0x0xjem@gmail.com> Date: Tue, 18 Nov 2025 13:36:23 +0400 Subject: [PATCH 2/3] chore: ignore linter warning --- src/Safe.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Safe.sol b/src/Safe.sol index a259b91..2a116bc 100644 --- a/src/Safe.sol +++ b/src/Safe.sol @@ -433,6 +433,7 @@ library Safe { vm.toString(nonce), ',"safeTxGas":"0"},"primaryType":"SafeTx","types":{"SafeTx":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"},{"name":"safeTxGas","type":"uint256"},{"name":"baseGas","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasToken","type":"address"},{"name":"refundReceiver","type":"address"},{"name":"nonce","type":"uint256"}]}}' ); + /// forge-lint: disable-next-line(unsafe-cheatcode) bytes memory output = vm.ffi(inputs); return output; } else { From 936701620231fb039dd2d6b8494d84bbf41b2d97 Mon Sep 17 00:00:00 2001 From: Jem <0x0xjem@gmail.com> Date: Tue, 18 Nov 2025 13:36:31 +0400 Subject: [PATCH 3/3] chore: formatting --- src/Safe.sol | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Safe.sol b/src/Safe.sol index 2a116bc..94d76e5 100644 --- a/src/Safe.sol +++ b/src/Safe.sol @@ -140,9 +140,8 @@ library Safe { Enum.Operation operation, uint256 nonce ) internal view returns (bytes32) { - return ISafeSmartAccount(instance(self).safe).getTransactionHash( - to, value, data, operation, 0, 0, 0, address(0), address(0), nonce - ); + return ISafeSmartAccount(instance(self).safe) + .getTransactionHash(to, value, data, operation, 0, 0, 0, address(0), address(0), nonce); } // https://github.com/safe-global/safe-core-sdk/blob/r60/packages/api-kit/src/SafeApiKit.ts#L574 @@ -160,14 +159,15 @@ library Safe { instance(self).requestBody = vm.serializeUint(".proposeTransaction", "gasPrice", 0); instance(self).requestBody = vm.serializeUint(".proposeTransaction", "nonce", params.nonce); - HTTP.Response memory response = instance(self).http.instance().POST( - string.concat( - getApiKitUrl(self, block.chainid), - "/v1/safes/", - vm.toString(instance(self).safe), - "/multisig-transactions/" - ) - ).withBody(instance(self).requestBody).request(); + HTTP.Response memory response = instance(self).http.instance() + .POST( + string.concat( + getApiKitUrl(self, block.chainid), + "/v1/safes/", + vm.toString(instance(self).safe), + "/multisig-transactions/" + ) + ).withBody(instance(self).requestBody).request(); // The response status should be 2xx, otherwise there was an issue if (response.status < 200 || response.status >= 300) {