Signing an Uint8Array (etherjs v6 => viem) #495
-
Hi, const hashToSign = ethers.solidityPackedKeccak256(
['address', 'uint256', 'uint256', 'uint256'],
[
myContratAddress,
nonce,
tokenId,
amount
]
);
const signature = await signer.signMessage(ethers.getBytes(hashToSign)); With viem, i (want to) do that : const hashToSign = keccak256(encodePacked(['address', 'uint256', 'uint256', 'uint256'],
[
myContractAddress,
BigInt(nonce),
BigInt(tokenId),
amount
]
const signature = await walletClient!.signMessage({ message: hashToSign }); My Back recover with Web3js : const message = web3.utils.soliditySha3(
{ type: 'address', value: myContractAddress },
{ type: 'uint256', value: nonce },
{ type: 'uint256', value: tokenId },
{ type: 'uint256', value: amount.toString() }
);
const recovered = web3.eth.accounts.recover(message!, signature); The back recovers correctly ether (and my contract also), but not viem (bad signer address). Note : If I add an arbitrary prefix like this : My solidity code : bytes32 message = prefixed(keccak256(abi.encodePacked(this, nonce, tokenId, price)));
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(message, vendorSigning);
// ...
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
} Can one help me please ? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
were you able to find answers? |
Beta Was this translation helpful? Give feedback.
-
Hi! Here an example I use for identification : My backend send a nonce to be signed. First create yours types like this : export const MyBackendDomain = {
name: 'MyBackendDomain',
version: '1'
} as const;
export const MyBackendTypes = {
linkWallet: [
{ name: 'action', type: 'string' },
{ name: 'account', type: 'address' },
{ name: 'nonce', type: 'uint256' },
],
otherType: [
{ name: 'params1', type: 'string' },
{ name: 'params2', type: 'address' },
{ name: 'params3', type: 'string' },
],
} as const; On your front, use const { address: userAccount } = useAccount();
const { data: walletClient } = useWalletClient();
/* (...) */
const signature = await walletClient.signTypedData({
domain: MyBackendDomain,
types: MyBackendTypes,
primaryType: 'linkWallet',
message: {
action: 'identification',
account: userAccount,
nonce: BigInt(nonce)
}
}); On your back : const isValid = await verifyTypedData({
address: userAccount,
domain: MyBackendDomain,
types: MyBackendTypes,
primaryType: 'linkWallet',
message: {
action: 'identification',
account: userAccount,
nonce: BigInt(nonce),
},
signature,
}); I rewrite this code for this example, i hop no error comes on |
Beta Was this translation helpful? Give feedback.
Hi!
Yes!
Here an example I use for identification : My backend send a nonce to be signed.
First create yours types like this :
On your front, use
signTypedData
: