From 203b7f46acbf300fa33e4bd4b6a296d9d570d3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Coffee=E2=98=95=EF=B8=8F?= Date: Wed, 2 Oct 2024 10:40:54 -0400 Subject: [PATCH 1/6] add ability to call deployed universal signature validator for chains that do not support createless call --- contracts/src/UniversalSigValidator.sol | 86 +++++++++++++++++++ .../DeploylessUniversalSigValidator.sol | 82 +----------------- src/actions/public/verifyHash.test.ts | 54 +++++++++++- src/actions/public/verifyHash.ts | 43 ++++++---- src/chains/definitions/abstractTestnet.ts | 4 + src/chains/definitions/zksync.ts | 4 + .../definitions/zksyncSepoliaTestnet.ts | 4 + src/constants/abis.ts | 24 ++++++ src/types/chain.ts | 1 + test/src/utils.ts | 8 ++ 10 files changed, 211 insertions(+), 99 deletions(-) create mode 100644 contracts/src/UniversalSigValidator.sol diff --git a/contracts/src/UniversalSigValidator.sol b/contracts/src/UniversalSigValidator.sol new file mode 100644 index 0000000000..e7e57bbede --- /dev/null +++ b/contracts/src/UniversalSigValidator.sol @@ -0,0 +1,86 @@ +pragma solidity ^0.8.17; + +// SPDX-License-Identifier: UNLICENSED + +// https://github.com/AmbireTech/signature-validator + +interface IERC1271Wallet { + function isValidSignature( + bytes32 hash, + bytes calldata signature + ) external view returns (bytes4 magicValue); +} + +contract VerifySig { + // ERC-6492 suffix: https://eips.ethereum.org/EIPS/eip-6492 + bytes32 private constant ERC6492_DETECTION_SUFFIX = + 0x6492649264926492649264926492649264926492649264926492649264926492; + bytes4 private constant ERC1271_SUCCESS = 0x1626ba7e; + + /** + * @notice Verifies that the signature is valid for that signer and hash + */ + function isValidUniversalSig( + address _signer, + bytes32 _hash, + bytes memory _signature + ) public returns (bool) { + // The order here is strictly defined in https://eips.ethereum.org/EIPS/eip-6492 + // - ERC-6492 suffix check and verification first, while being permissive in case the contract is already deployed so as to not invalidate old sigs + // - ERC-1271 verification if there's contract code + // - finally, ecrecover + if (trailingBytes32(_signature) == ERC6492_DETECTION_SUFFIX) { + address create2Factory; + bytes memory factoryCalldata; + bytes memory originalSig; + (create2Factory, factoryCalldata, originalSig) = abi.decode( + _signature, + (address, bytes, bytes) + ); + + (bool success, ) = create2Factory.call(factoryCalldata); + + if (_signer.code.length == 0) { + require(success, "SignatureValidator: deployment"); + } + + return + IERC1271Wallet(_signer).isValidSignature(_hash, originalSig) == + ERC1271_SUCCESS; + } + + if (_signer.code.length > 0) { + return + IERC1271Wallet(_signer).isValidSignature(_hash, _signature) == + ERC1271_SUCCESS; + } + + // ecrecover verification + require( + _signature.length == 65, + "SignatureValidator#recoverSigner: invalid signature length" + ); + bytes32[3] memory _sig; + assembly { + _sig := _signature + } + bytes32 r = _sig[1]; + bytes32 s = _sig[2]; + uint8 v = uint8(_signature[64]); + if (v != 27 && v != 28) { + revert( + "SignatureValidator#recoverSigner: invalid signature v value" + ); + } + return ecrecover(_hash, v, r, s) == _signer; + } + + function trailingBytes32( + bytes memory data + ) internal pure returns (bytes32 ret) { + require(data.length >= 32); + assembly { + ret := mload(add(data, mload(data))) + } + } +} diff --git a/contracts/src/deployless/DeploylessUniversalSigValidator.sol b/contracts/src/deployless/DeploylessUniversalSigValidator.sol index 4158a73d38..c4a9381020 100644 --- a/contracts/src/deployless/DeploylessUniversalSigValidator.sol +++ b/contracts/src/deployless/DeploylessUniversalSigValidator.sol @@ -3,15 +3,9 @@ pragma solidity ^0.8.17; // SPDX-License-Identifier: UNLICENSED // https://github.com/AmbireTech/signature-validator +import { VerifySig } from "../UniversalSigValidator.sol"; -interface IERC1271Wallet { - function isValidSignature( - bytes32 hash, - bytes calldata signature - ) external view returns (bytes4 magicValue); -} - -contract VerifySig { +contract DeploylessVerifySig is VerifySig { constructor(address _signer, bytes32 _hash, bytes memory _signature) { bool isValidSig = isValidUniversalSig(_signer, _hash, _signature); assembly { @@ -19,76 +13,4 @@ contract VerifySig { return(31, 1) } } - - // ERC-6492 suffix: https://eips.ethereum.org/EIPS/eip-6492 - bytes32 private constant ERC6492_DETECTION_SUFFIX = - 0x6492649264926492649264926492649264926492649264926492649264926492; - bytes4 private constant ERC1271_SUCCESS = 0x1626ba7e; - - /** - * @notice Verifies that the signature is valid for that signer and hash - */ - function isValidUniversalSig( - address _signer, - bytes32 _hash, - bytes memory _signature - ) public returns (bool) { - // The order here is strictly defined in https://eips.ethereum.org/EIPS/eip-6492 - // - ERC-6492 suffix check and verification first, while being permissive in case the contract is already deployed so as to not invalidate old sigs - // - ERC-1271 verification if there's contract code - // - finally, ecrecover - if (trailingBytes32(_signature) == ERC6492_DETECTION_SUFFIX) { - address create2Factory; - bytes memory factoryCalldata; - bytes memory originalSig; - (create2Factory, factoryCalldata, originalSig) = abi.decode( - _signature, - (address, bytes, bytes) - ); - - (bool success, ) = create2Factory.call(factoryCalldata); - - if (_signer.code.length == 0) { - require(success, "SignatureValidator: deployment"); - } - - return - IERC1271Wallet(_signer).isValidSignature(_hash, originalSig) == - ERC1271_SUCCESS; - } - - if (_signer.code.length > 0) { - return - IERC1271Wallet(_signer).isValidSignature(_hash, _signature) == - ERC1271_SUCCESS; - } - - // ecrecover verification - require( - _signature.length == 65, - "SignatureValidator#recoverSigner: invalid signature length" - ); - bytes32[3] memory _sig; - assembly { - _sig := _signature - } - bytes32 r = _sig[1]; - bytes32 s = _sig[2]; - uint8 v = uint8(_signature[64]); - if (v != 27 && v != 28) { - revert( - "SignatureValidator#recoverSigner: invalid signature v value" - ); - } - return ecrecover(_hash, v, r, s) == _signer; - } - - function trailingBytes32( - bytes memory data - ) internal pure returns (bytes32 ret) { - require(data.length >= 32); - assembly { - ret := mload(add(data, mload(data))) - } - } } diff --git a/src/actions/public/verifyHash.test.ts b/src/actions/public/verifyHash.test.ts index a442d47d1f..750c05239a 100644 --- a/src/actions/public/verifyHash.test.ts +++ b/src/actions/public/verifyHash.test.ts @@ -7,7 +7,10 @@ import { import { ensPublicResolverConfig, smartAccountConfig } from '~test/src/abis.js' import { anvilMainnet } from '~test/src/anvil.js' import { accounts, address } from '~test/src/constants.js' -import { deploySoladyAccount_07 } from '~test/src/utils.js' +import { + deploySoladyAccount_07, + deployUniversalSignatureVerifier, +} from '~test/src/utils.js' import { entryPoint07Abi, entryPoint07Address, @@ -151,6 +154,55 @@ describe('smart account', async () => { ).resolves.toBe(true) }) + test('undeployed with predeployed verifier', async () => { + const { factoryAddress } = await deploySoladyAccount_07() + const { contractAddress: verifySig } = + await deployUniversalSignatureVerifier() + + const overrideClient = { + ...client, + chain: { + ...client.chain, + contracts: { + ...client.chain.contracts, + universalSignatureVerifier: { address: verifySig }, + }, + }, + } + + const { result: verifier } = await simulateContract(overrideClient, { + account: localAccount, + abi: SoladyAccountFactory07.abi, + address: factoryAddress, + functionName: 'createAccount', + args: [localAccount.address, pad('0x0')], + }) + + const factoryData = encodeFunctionData({ + abi: SoladyAccountFactory07.abi, + functionName: 'createAccount', + args: [localAccount.address, pad('0x0')], + }) + + const signature = await signMessageErc1271(overrideClient, { + account: localAccount, + factory: factoryAddress, + factoryData, + message: 'hello world', + verifier, + }) + + expect( + verifyHash(overrideClient, { + address: verifier, + factory: factoryAddress, + factoryData, + hash: hashMessage('hello world'), + signature, + }), + ).resolves.toBe(true) + }) + test('deployed w/ factory + factoryData', async () => { const { factoryAddress } = await deploySoladyAccount_07() diff --git a/src/actions/public/verifyHash.ts b/src/actions/public/verifyHash.ts index 00cb678286..f85b59eb99 100644 --- a/src/actions/public/verifyHash.ts +++ b/src/actions/public/verifyHash.ts @@ -1,10 +1,12 @@ import type { Address } from 'abitype' +import { encodeFunctionData, hexToBool } from '~viem/utils/index.js' import type { Client } from '../../clients/createClient.js' import type { Transport } from '../../clients/transports/createTransport.js' import { universalSignatureValidatorAbi } from '../../constants/abis.js' import { universalSignatureValidatorByteCode } from '../../constants/contracts.js' import { CallExecutionError } from '../../errors/contract.js' +import type { InvalidHexBooleanError } from '../../errors/encoding.js' import type { ErrorType } from '../../errors/utils.js' import type { Chain } from '../../types/chain.js' import type { ByteArray, Hex, Signature } from '../../types/misc.js' @@ -15,10 +17,6 @@ import { } from '../../utils/abi/encodeDeployData.js' import { getAddress } from '../../utils/address/getAddress.js' import { isAddressEqual } from '../../utils/address/isAddressEqual.js' -import { - type IsBytesEqualErrorType, - isBytesEqual, -} from '../../utils/data/isBytesEqual.js' import { type IsHexErrorType, isHex } from '../../utils/data/isHex.js' import { type ToHexErrorType, bytesToHex } from '../../utils/encoding/toHex.js' import { getAction } from '../../utils/getAction.js' @@ -46,7 +44,7 @@ export type VerifyHashErrorType = | CallErrorType | IsHexErrorType | ToHexErrorType - | IsBytesEqualErrorType + | InvalidHexBooleanError | EncodeDeployDataErrorType | ErrorType @@ -88,20 +86,29 @@ export async function verifyHash( })() try { - const { data } = await getAction( - client, - call, - 'call', - )({ - data: encodeDeployData({ - abi: universalSignatureValidatorAbi, - args: [address, hash, wrappedSignature], - bytecode: universalSignatureValidatorByteCode, - }), - ...rest, - } as unknown as CallParameters) + const callParameters: CallParameters = client.chain?.contracts + ?.universalSignatureVerifier + ? ({ + to: client.chain.contracts.universalSignatureVerifier.address, + data: encodeFunctionData({ + abi: universalSignatureValidatorAbi, + functionName: 'isValidUniversalSig', + args: [address, hash, wrappedSignature], + }), + ...rest, + } as unknown as CallParameters) + : ({ + data: encodeDeployData({ + abi: universalSignatureValidatorAbi, + args: [address, hash, wrappedSignature], + bytecode: universalSignatureValidatorByteCode, + }), + ...rest, + } as unknown as CallParameters) + + const { data } = await getAction(client, call, 'call')(callParameters) - return isBytesEqual(data ?? '0x0', '0x1') + return hexToBool(data ?? '0x0') } catch (error) { // Fallback attempt to verify the signature via ECDSA recovery. try { diff --git a/src/chains/definitions/abstractTestnet.ts b/src/chains/definitions/abstractTestnet.ts index 3446c0279b..b3c2b618e4 100644 --- a/src/chains/definitions/abstractTestnet.ts +++ b/src/chains/definitions/abstractTestnet.ts @@ -25,5 +25,9 @@ export const abstractTestnet = /*#__PURE__*/ defineChain({ address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', blockCreated: 358349, }, + universalSignatureVerifier: { + address: '0x872146211f996755C8729042093ffb8660F8b129', + blockCreated: 431682, + }, }, }) diff --git a/src/chains/definitions/zksync.ts b/src/chains/definitions/zksync.ts index fd55b95b9d..b118d8b311 100644 --- a/src/chains/definitions/zksync.ts +++ b/src/chains/definitions/zksync.ts @@ -33,5 +33,9 @@ export const zksync = /*#__PURE__*/ defineChain({ multicall3: { address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', }, + universalSignatureVerifier: { + address: '0x872146211f996755C8729042093ffb8660F8b129', + blockCreated: 45659388, + }, }, }) diff --git a/src/chains/definitions/zksyncSepoliaTestnet.ts b/src/chains/definitions/zksyncSepoliaTestnet.ts index 0c8fa41d66..197380d9cb 100644 --- a/src/chains/definitions/zksyncSepoliaTestnet.ts +++ b/src/chains/definitions/zksyncSepoliaTestnet.ts @@ -29,6 +29,10 @@ export const zksyncSepoliaTestnet = /*#__PURE__*/ defineChain({ multicall3: { address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', }, + universalSignatureVerifier: { + address: '0x872146211f996755C8729042093ffb8660F8b129', + blockCreated: 3855712, + }, }, testnet: true, }) diff --git a/src/constants/abis.ts b/src/constants/abis.ts index 670a2c5e2c..2acdd42c3b 100644 --- a/src/constants/abis.ts +++ b/src/constants/abis.ts @@ -224,6 +224,30 @@ export const universalSignatureValidatorAbi = [ stateMutability: 'nonpayable', type: 'constructor', }, + { + inputs: [ + { + name: '_signer', + type: 'address', + }, + { + name: '_hash', + type: 'bytes32', + }, + { + name: '_signature', + type: 'bytes', + }, + ], + outputs: [ + { + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + name: 'isValidUniversalSig', + }, ] as const /** [ERC-20 Token Standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20) */ diff --git a/src/types/chain.ts b/src/types/chain.ts index 3caeef921b..a6dbe406e8 100644 --- a/src/types/chain.ts +++ b/src/types/chain.ts @@ -40,6 +40,7 @@ export type Chain< ensRegistry?: ChainContract | undefined ensUniversalResolver?: ChainContract | undefined multicall3?: ChainContract | undefined + universalSignatureVerifier?: ChainContract | undefined } > | undefined diff --git a/test/src/utils.ts b/test/src/utils.ts index ee0581f6ff..6d35d8b367 100644 --- a/test/src/utils.ts +++ b/test/src/utils.ts @@ -34,6 +34,7 @@ import { SoladyAccount07, SoladyAccountFactory06, SoladyAccountFactory07, + VerifySig, } from '../../contracts/generated.js' import { baycContractConfig, @@ -171,6 +172,13 @@ export async function deploySoladyAccount_06() { } } +export async function deployUniversalSignatureVerifier() { + return deploy(client, { + abi: VerifySig.abi, + bytecode: VerifySig.bytecode.object, + }) +} + export async function setVitalikResolver() { await impersonateAccount(client, { address: address.vitalik, From bc8e709b85ed342cdc3f93cb04aac02207022698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Coffee=E2=98=95=EF=B8=8F?= Date: Wed, 2 Oct 2024 10:47:09 -0400 Subject: [PATCH 2/6] fix import --- src/actions/public/verifyHash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/public/verifyHash.ts b/src/actions/public/verifyHash.ts index f85b59eb99..32640044b3 100644 --- a/src/actions/public/verifyHash.ts +++ b/src/actions/public/verifyHash.ts @@ -1,6 +1,5 @@ import type { Address } from 'abitype' -import { encodeFunctionData, hexToBool } from '~viem/utils/index.js' import type { Client } from '../../clients/createClient.js' import type { Transport } from '../../clients/transports/createTransport.js' import { universalSignatureValidatorAbi } from '../../constants/abis.js' @@ -20,6 +19,7 @@ import { isAddressEqual } from '../../utils/address/isAddressEqual.js' import { type IsHexErrorType, isHex } from '../../utils/data/isHex.js' import { type ToHexErrorType, bytesToHex } from '../../utils/encoding/toHex.js' import { getAction } from '../../utils/getAction.js' +import { encodeFunctionData, hexToBool } from '../../utils/index.js' import { isErc6492Signature } from '../../utils/signature/isErc6492Signature.js' import { recoverAddress } from '../../utils/signature/recoverAddress.js' import { serializeErc6492Signature } from '../../utils/signature/serializeErc6492Signature.js' From ccc83eccfee351b1a1b08fa7701a6f7a791b7407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Coffee=E2=98=95=EF=B8=8F?= Date: Wed, 2 Oct 2024 10:56:01 -0400 Subject: [PATCH 3/6] remove unused isBytesEqual util --- src/utils/data/isBytesEqual.test.ts | 19 ------------------- src/utils/data/isBytesEqual.ts | 17 ----------------- 2 files changed, 36 deletions(-) delete mode 100644 src/utils/data/isBytesEqual.test.ts delete mode 100644 src/utils/data/isBytesEqual.ts diff --git a/src/utils/data/isBytesEqual.test.ts b/src/utils/data/isBytesEqual.test.ts deleted file mode 100644 index a524da6c62..0000000000 --- a/src/utils/data/isBytesEqual.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { expect, test } from 'vitest' - -import { isBytesEqual } from './isBytesEqual.js' - -test('is bytes', () => { - // true - expect( - isBytesEqual(new Uint8Array([1, 69, 420]), new Uint8Array([1, 69, 420])), - ).toBeTruthy() - expect(isBytesEqual('0x1', '0x1')).toBeTruthy() - expect(isBytesEqual('0x1', '0x01')).toBeTruthy() - - // false - expect( - isBytesEqual(new Uint8Array([1, 69, 420]), new Uint8Array([1, 69, 421])), - ).toBeFalsy() - expect(isBytesEqual('0x1', '0x2')).toBeFalsy() - expect(isBytesEqual('0x1', '0x10')).toBeFalsy() -}) diff --git a/src/utils/data/isBytesEqual.ts b/src/utils/data/isBytesEqual.ts deleted file mode 100644 index bdb6ca0f7f..0000000000 --- a/src/utils/data/isBytesEqual.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { equalBytes } from '@noble/curves/abstract/utils' - -import type { ErrorType } from '../../errors/utils.js' -import type { ByteArray, Hex } from '../../types/misc.js' -import { type ToBytesErrorType, toBytes } from '../encoding/toBytes.js' -import { type IsHexErrorType, isHex } from './isHex.js' - -export type IsBytesEqualErrorType = - | IsHexErrorType - | ToBytesErrorType - | ErrorType - -export function isBytesEqual(a_: ByteArray | Hex, b_: ByteArray | Hex) { - const a = isHex(a_) ? toBytes(a_) : a_ - const b = isHex(b_) ? toBytes(b_) : b_ - return equalBytes(a, b) -} From 688911b8a5277182c5beff7a32328a4dec11799c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Coffee=E2=98=95=EF=B8=8F?= Date: Mon, 7 Oct 2024 10:21:06 -0400 Subject: [PATCH 4/6] update function name to `isValidSig` --- contracts/src/UniversalSigValidator.sol | 2 +- contracts/src/deployless/DeploylessUniversalSigValidator.sol | 4 ++-- src/actions/public/verifyHash.ts | 2 +- src/constants/abis.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/src/UniversalSigValidator.sol b/contracts/src/UniversalSigValidator.sol index e7e57bbede..17eb6f74bb 100644 --- a/contracts/src/UniversalSigValidator.sol +++ b/contracts/src/UniversalSigValidator.sol @@ -20,7 +20,7 @@ contract VerifySig { /** * @notice Verifies that the signature is valid for that signer and hash */ - function isValidUniversalSig( + function isValidSig( address _signer, bytes32 _hash, bytes memory _signature diff --git a/contracts/src/deployless/DeploylessUniversalSigValidator.sol b/contracts/src/deployless/DeploylessUniversalSigValidator.sol index c4a9381020..ff1dd4a175 100644 --- a/contracts/src/deployless/DeploylessUniversalSigValidator.sol +++ b/contracts/src/deployless/DeploylessUniversalSigValidator.sol @@ -7,9 +7,9 @@ import { VerifySig } from "../UniversalSigValidator.sol"; contract DeploylessVerifySig is VerifySig { constructor(address _signer, bytes32 _hash, bytes memory _signature) { - bool isValidSig = isValidUniversalSig(_signer, _hash, _signature); + bool isValid = isValidSig(_signer, _hash, _signature); assembly { - mstore(0, isValidSig) + mstore(0, isValid) return(31, 1) } } diff --git a/src/actions/public/verifyHash.ts b/src/actions/public/verifyHash.ts index 32640044b3..3760de6d9f 100644 --- a/src/actions/public/verifyHash.ts +++ b/src/actions/public/verifyHash.ts @@ -92,7 +92,7 @@ export async function verifyHash( to: client.chain.contracts.universalSignatureVerifier.address, data: encodeFunctionData({ abi: universalSignatureValidatorAbi, - functionName: 'isValidUniversalSig', + functionName: 'isValidSig', args: [address, hash, wrappedSignature], }), ...rest, diff --git a/src/constants/abis.ts b/src/constants/abis.ts index 2acdd42c3b..0d0500e8b3 100644 --- a/src/constants/abis.ts +++ b/src/constants/abis.ts @@ -246,7 +246,7 @@ export const universalSignatureValidatorAbi = [ ], stateMutability: 'nonpayable', type: 'function', - name: 'isValidUniversalSig', + name: 'isValidSig', }, ] as const From bcda6ffe22da8700bb697b52d3b68030e4f8e661 Mon Sep 17 00:00:00 2001 From: jxom Date: Sun, 13 Oct 2024 17:42:23 +1100 Subject: [PATCH 5/6] chore: tweaks --- src/actions/public/verifyHash.test.ts | 41 ++++++++++++++++++++++++++- src/actions/public/verifyHash.ts | 19 +++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/actions/public/verifyHash.test.ts b/src/actions/public/verifyHash.test.ts index 750c05239a..801aedaf3e 100644 --- a/src/actions/public/verifyHash.test.ts +++ b/src/actions/public/verifyHash.test.ts @@ -154,7 +154,46 @@ describe('smart account', async () => { ).resolves.toBe(true) }) - test('undeployed with predeployed verifier', async () => { + test('undeployed with predeployed verifier (via arg)', async () => { + const { factoryAddress } = await deploySoladyAccount_07() + const { contractAddress: universalSignatureVerifierAddress } = + await deployUniversalSignatureVerifier() + + const { result: verifier } = await simulateContract(client, { + account: localAccount, + abi: SoladyAccountFactory07.abi, + address: factoryAddress, + functionName: 'createAccount', + args: [localAccount.address, pad('0x0')], + }) + + const factoryData = encodeFunctionData({ + abi: SoladyAccountFactory07.abi, + functionName: 'createAccount', + args: [localAccount.address, pad('0x0')], + }) + + const signature = await signMessageErc1271(client, { + account: localAccount, + factory: factoryAddress, + factoryData, + message: 'hello world', + verifier, + }) + + expect( + verifyHash(client, { + address: verifier, + factory: factoryAddress, + factoryData, + hash: hashMessage('hello world'), + signature, + universalSignatureVerifierAddress: universalSignatureVerifierAddress!, + }), + ).resolves.toBe(true) + }) + + test('undeployed with predeployed verifier (via client)', async () => { const { factoryAddress } = await deploySoladyAccount_07() const { contractAddress: verifySig } = await deployUniversalSignatureVerifier() diff --git a/src/actions/public/verifyHash.ts b/src/actions/public/verifyHash.ts index 3760de6d9f..4478a3ce93 100644 --- a/src/actions/public/verifyHash.ts +++ b/src/actions/public/verifyHash.ts @@ -36,6 +36,7 @@ export type VerifyHashParameters = Pick< hash: Hex /** The signature that was generated by signing the message with the address's private key. */ signature: Hex | ByteArray | Signature + universalSignatureVerifierAddress?: Address | undefined } & OneOf<{ factory: Address; factoryData: Hex } | {}> export type VerifyHashReturnType = boolean @@ -59,7 +60,16 @@ export async function verifyHash( client: Client, parameters: VerifyHashParameters, ): Promise { - const { address, factory, factoryData, hash, signature, ...rest } = parameters + const { + address, + factory, + factoryData, + hash, + signature, + universalSignatureVerifierAddress = client.chain?.contracts + ?.universalSignatureVerifier?.address, + ...rest + } = parameters const signatureHex = (() => { if (isHex(signature)) return signature @@ -86,10 +96,9 @@ export async function verifyHash( })() try { - const callParameters: CallParameters = client.chain?.contracts - ?.universalSignatureVerifier + const args = universalSignatureVerifierAddress ? ({ - to: client.chain.contracts.universalSignatureVerifier.address, + to: universalSignatureVerifierAddress, data: encodeFunctionData({ abi: universalSignatureValidatorAbi, functionName: 'isValidSig', @@ -106,7 +115,7 @@ export async function verifyHash( ...rest, } as unknown as CallParameters) - const { data } = await getAction(client, call, 'call')(callParameters) + const { data } = await getAction(client, call, 'call')(args) return hexToBool(data ?? '0x0') } catch (error) { From 39c6696122acdc66fe5b411c02322897aefb0896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Coffee=E2=98=95=EF=B8=8F?= Date: Sun, 13 Oct 2024 10:48:07 -0400 Subject: [PATCH 6/6] update addresse for new deployment --- src/chains/definitions/abstractTestnet.ts | 2 +- src/chains/definitions/zksync.ts | 2 +- src/chains/definitions/zksyncSepoliaTestnet.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chains/definitions/abstractTestnet.ts b/src/chains/definitions/abstractTestnet.ts index b3c2b618e4..a5033e957d 100644 --- a/src/chains/definitions/abstractTestnet.ts +++ b/src/chains/definitions/abstractTestnet.ts @@ -26,7 +26,7 @@ export const abstractTestnet = /*#__PURE__*/ defineChain({ blockCreated: 358349, }, universalSignatureVerifier: { - address: '0x872146211f996755C8729042093ffb8660F8b129', + address: '0xfB688330379976DA81eB64Fe4BF50d7401763B9C', blockCreated: 431682, }, }, diff --git a/src/chains/definitions/zksync.ts b/src/chains/definitions/zksync.ts index b118d8b311..5c0706b55f 100644 --- a/src/chains/definitions/zksync.ts +++ b/src/chains/definitions/zksync.ts @@ -34,7 +34,7 @@ export const zksync = /*#__PURE__*/ defineChain({ address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', }, universalSignatureVerifier: { - address: '0x872146211f996755C8729042093ffb8660F8b129', + address: '0xfB688330379976DA81eB64Fe4BF50d7401763B9C', blockCreated: 45659388, }, }, diff --git a/src/chains/definitions/zksyncSepoliaTestnet.ts b/src/chains/definitions/zksyncSepoliaTestnet.ts index 197380d9cb..955553e704 100644 --- a/src/chains/definitions/zksyncSepoliaTestnet.ts +++ b/src/chains/definitions/zksyncSepoliaTestnet.ts @@ -30,7 +30,7 @@ export const zksyncSepoliaTestnet = /*#__PURE__*/ defineChain({ address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', }, universalSignatureVerifier: { - address: '0x872146211f996755C8729042093ffb8660F8b129', + address: '0xfB688330379976DA81eB64Fe4BF50d7401763B9C', blockCreated: 3855712, }, },