I want an unsigned payload to sign a transaction later with a ECDSA Private key.
This is a MPC wallet so I don’t have the private key directly. The process is:
- I send the unsigned transaction payload like below:
web3 = Web3(Web3.HTTPProvider(rpc_url))
nonce = web3.eth.get_transaction_count(web3.to_checksum_address(send_signature.to_address.lower()))
transaction = {
"nonce": nonce,
"to": web3.to_checksum_address(send_signature.to_address.lower()),
"value": web3.to_wei('0.002, "ether"),
"gas": 21000,
"maxPriorityFeePerGas": web3.to_wei("5", "gwei"),
"maxFeePerGas": web3.to_wei("15", "gwei"),
"chainId": 56,
"type": 2,
}
# Encode the transaction for hashing
tx_message = [
transaction["nonce"],
transaction["maxPriorityFeePerGas"],
transaction["maxFeePerGas"],
transaction["gas"],
bytes.fromhex(transaction["to"][2:]),
transaction["value"],
b"", # data field
[], # access list
transaction["chainId"],
transaction["type"],
]
encoded_tx = rlp.encode(tx_message)
serialized_tx = keccak(encoded_tx).hex()
data = {"kind": "Hash", "hash": serialized_tx}
- After the mpc wallet signs the message and returns the data as signature as follows:
{'id': 'sig-98667-gl6f8', 'walletId': 'wa-3q6ek-if17t', 'network': 'KeyECDSA', 'requester': {'userId': 'us-1r68b', 'appId': 'ap'}, 'requestBody': {'kind': 'Hash', 'hash': 'e3a4ca418a03227e9f6db95ded00acef0b86457a71b39818aebf7a3b4dee040c'}, 'status': 'Signed', 'signature': {'r': '0x5f654363ecd0620b53927c5e9ee000870ce009612f9864844xxxxxx', 's': '0x51bf7042f9dfdbd698ee06e659bed7f93f3d902ad8eb16065c1d6f611430f06e', 'recid': 0}, 'dateRequested': '2024-07-28T07:57:46.313Z', 'dateSigned': '2024-07-28T07:57:48.071Z'}
- When I try to publish this transaction:
chain_id = 56
signature = {
"r": int(broadcast_data["signature"]["r"], 16),
"s": int(broadcast_data["signature"]["s"], 16),
"v": int(broadcast_data["signature"]["recid"]) + 35 + 2 * chain_id,
}
signed_tx_message = txn_message + [
signature["v"],
to_bytes(signature["r"]),
to_bytes(signature["s"]),
]
encoded_signed_tx = rlp.encode(signed_tx_message)
tx_hash = web3.eth.send_raw_transaction(encoded_signed_tx)
I get the following error:
ValueError: {'code': -32000, 'message': 'unmarshal transaction failed'}
References:
- https://docs.dfns.co/d/api-docs/wallets/generate-signature-from-wallet/pseudo-networks-all-other-chains-generate-signature