Open rhamnett opened 3 days ago
Perhaps this method can be updated? Although you may have a better suggestion.
key_service.dart
ChainKey _eip155ChainKey(CryptoKeyPair keyPair) {
final private = EthPrivateKey.fromHex(keyPair.privateKey);
final address = private.address.hexEip55; <<<HERE!!!
final evmChainKey = ChainKey(
chains: ChainsDataList.eip155Chains.map((e) => e.chainId).toList(),
privateKey: keyPair.privateKey,
publicKey: keyPair.publicKey,
address: address,
);
debugPrint('[SampleWallet] evmChainKey ${evmChainKey.toString()}');
return evmChainKey;
}
I did provide a fix to my server side, which converts the siweAddress to checksummed, but don't you agree this should be something we send correctly from the client in the first place?
Cheers
Hello @rhamnett, can you provide steps to repro (specific wallet as well)? Coz I tried with our internal Swift wallet (which does support ERC-55) and I have no issues.
Hello, I am simply verifying the SIWE message in typescript using import { generateNonce, SiweMessage } from 'siwe';
. I have had to overwrite the address in the message created by reown as it does not conform strictly to adding the wallet address as a checksummed address.
In my opinion, the message should be transmitted with the correct type of checksummed address in the message, or the checksum is effectively not useful.
The message is created in Flutter using your util method:
createMessage: (SIWECreateMessageArgs args) {
// Create SIWE message to be signed.
// You can use our provided formatMessage() method of implement your own
return SIWEUtils.formatMessage(args);
},
Server code:
let siweMessage: SiweMessage;
try {
try {
siweMessage = new SiweMessage(message);
siweMessage.address = ethers.utils.getAddress(siweMessage.address); <<note this hack to fix the address
} catch (error) {
throw new Error(`Invalid SIWE message, ${error}`);
}
console.log(
`[Auth] Parsed SIWE Message: ${JSON.stringify(siweMessage)} `
);
// Define actual domain
console.log(`[Auth] Verification Domain: ${siweMessage.domain}`);
// Perform verification
try {
const fields = await siweMessage.verify({
signature,
domain: siweMessage.domain,
nonce: nonceFromToken,
});
if (!fields.success) {
throw new Error('Signature verification failed');
}
console.log(
`[Auth] SIWE message verified successfully: ${JSON.stringify(
fields
)}`
);
} catch (error) {
throw new Error(`Signature verification failed: ${error}`);
}
The above code will fail if the address isn't overwritten with error SIWE verification failed: Invalid SIWE message, Error: Address not conformant to EIP-55
I suppose you could also look to enhance the SIWEUtils.formatMessage()
method.
Many thanks Rich
Yes, ERC-55 has still to be supported on flutter SDK, however this shouldn't be a reason for wallets to reject/invalidate the signing as you mention in the original comment:
When I connect the appkit modal example to a wallet that uses the latest walletkit, the SIWE fails because the signing message does not use a checksummed address.
This is what concerns me. 👆
Can you try by replacing this:
createMessage: (SIWECreateMessageArgs args) {
// Create SIWE message to be signed.
// You can use our provided formatMessage() method of implement your own
return SIWEUtils.formatMessage(args);
},
With this:
createMessage: (SIWECreateMessageArgs args) {
// Create SIWE message to be signed.
// You can use our provided formatMessage() method of implement your own
final authPayload = SessionAuthPayload.fromJson(args.toJson()).copyWith(
chains: [args.chainId],
aud: args.uri,
type: args.type?.t ?? 'eip4361',
);
final account = NamespaceUtils.getAccount(args.address);
final address = EthereumAddress.fromHex(account);
return _appKitModal.appKit!.formatAuthMessage(
iss: 'did:pkh:${args.chainId}:${address.hexEip55}',
cacaoPayload: CacaoRequestPayload.fromSessionAuthPayload(
authPayload,
),
);
},
@quetool i think it's simply that the SIWE node implementation checks to ensure the wallet address is EIP-55 ( see https://github.com/spruceid/siwe/blob/940a66ac3dc7443b52d04fcdcebe5a6d889add9b/packages/siwe/lib/client.ts#L428 ) and fails hard.
On the flutter side, when the wallet is created from a seedphrase in the example code... the wallet is created with .hex and not .hexEip55.
I've added my own fix on both the flutter side and the server side to ensure that a checksummed wallet is generated & checked in the message.
I did ask ChatGPT and it says
The EIP-4361 standard specifies how the message is structured, but it does not explicitly mandate the use of a checksummed address.
So I guess this is up to you if you want to adjust your implementation to send a checksummed address. If not then please do feel free to close the ticket. It was simply a suggestion :)
We agree! I think there's a miscommunication here LMAO so let's try to strip this convo down:
createMessage: (SIWECreateMessageArgs args) {}
definition on host side (sample dapp) with the one I provided to overcome the server-side check. (this was the goal on my comments, not disagreeing with you)We are on the same page! Thanks for the feedback! Keep it coming, please!
OK thanks :)
I certainly didn't take anything as if we were disagreeing, I was simply trying to clarify how I'd worked around (I'd changed the way the wallet key is imported to checksum it).
Your solution looks to do the job as well, in a different manner. Apologies if any crossed wires and thanks also for the feedback and great communication!
Let's keep it open as a reminder that we must support ERC-55! 💯
Describe the bug
When I connect the appkit modal example to a wallet that uses the latest walletkit, the SIWE fails because the signing message does not use a checksummed address.
Error:
The address in the message should start 0x958C690D6Cb8d4.... note the capital C after 0x958....