Skip to content

Commit 877b50e

Browse files
committed
Proper flow, failing RLP
1 parent a63a7b4 commit 877b50e

File tree

2 files changed

+45
-77
lines changed

2 files changed

+45
-77
lines changed

Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ public static async Task<string> Send(ThirdwebTransaction transaction, string zk
243243
};
244244
Console.WriteLine($"ZkSync transaction: {JsonConvert.SerializeObject(zkTx)}");
245245
var zkTxSigned = await EIP712.GenerateSignature_ZkSyncTransaction("zkSync", "2", transaction.Input.ChainId.Value, zkTx, transaction._wallet);
246+
Console.WriteLine($"ZkSync transaction signed: {zkTxSigned}");
246247
hash = await rpc.SendRequestAsync<string>("eth_sendRawTransaction", zkTxSigned);
247248
}
248249
else
Lines changed: 44 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
using System.Numerics;
22
using Nethereum.ABI.EIP712;
33
using Nethereum.Hex.HexConvertors.Extensions;
4+
using Nethereum.Model;
45
using Nethereum.RLP;
56
using Nethereum.Signer;
7+
using Nethereum.Signer.Crypto;
68
using Nethereum.Signer.EIP712;
9+
using Nethereum.Util;
710
using Newtonsoft.Json;
811

912
namespace Thirdweb
@@ -46,29 +49,15 @@ IThirdwebWallet signer
4649
)
4750
{
4851
var typedData = GetTypedDefinition_ZkSyncTransaction(domainName, version, chainId, transaction.From);
49-
return await signer.SignTypedDataV4(transaction, typedData);
50-
}
51-
52-
// private static EthECDSASignature ParseSignature(string signatureHex)
53-
// {
54-
// var signatureBytes = signatureHex.HexToByteArray();
55-
// if (signatureBytes.Length != 65)
56-
// {
57-
// throw new ArgumentException("Invalid signature length.");
58-
// }
59-
60-
// var r = new byte[32];
61-
// var s = new byte[32];
62-
// var v = new byte[1];
63-
64-
// Array.Copy(signatureBytes, 0, r, 0, 32);
65-
// Array.Copy(signatureBytes, 32, s, 0, 32);
66-
// Array.Copy(signatureBytes, 64, v, 0, 1);
6752

68-
// var vValue = (v[0] == 0 || v[0] == 1) ? v[0] + 27 : v[0]; // Adjust v value if necessary
69-
70-
// return new EthECDSASignature(new Org.BouncyCastle.Math.BigInteger(r), new Org.BouncyCastle.Math.BigInteger(s), vValue.ToBytesForRLPEncoding());
71-
// }
53+
var typedDataSigner = new Eip712TypedDataSigner();
54+
var encodedTypedData = typedDataSigner.EncodeTypedData(transaction, typedData);
55+
var hash = new Sha3Keccack().CalculateHash(encodedTypedData);
56+
var signatureHex = await signer.EthSign(hash);
57+
var signatureRaw = ECDSASignatureFactory.ExtractECDSASignature(signatureHex);
58+
var serializedTx = SerializeEip712(transaction, signatureRaw, signatureHex, chainId);
59+
return serializedTx;
60+
}
7261

7362
public static TypedData<Domain> GetTypedDefinition_SmartAccount(string domainName, string version, BigInteger chainId, string verifyingContract)
7463
{
@@ -118,61 +107,39 @@ public static TypedData<Domain> GetTypedDefinition_ZkSyncTransaction(string doma
118107
};
119108
}
120109

121-
// private static string SerializeEip712(AccountAbstraction.ZkSyncAATransaction transaction, EthECDSASignature signature, BigInteger chainId)
122-
// {
123-
// if (transaction.From == null)
124-
// {
125-
// throw new ArgumentException("Explicitly providing `from` field is required for EIP712 transactions!");
126-
// }
127-
128-
// var fields = new List<byte[]>
129-
// {
130-
// RLP.EncodeElement(transaction.Nonce.ToByteArray()),
131-
// RLP.EncodeElement(transaction.MaxPriorityFeePerGas.ToByteArray()),
132-
// RLP.EncodeElement(transaction.MaxFeePerGas.ToByteArray()),
133-
// RLP.EncodeElement(transaction.GasLimit.ToByteArray()),
134-
// RLP.EncodeElement(transaction.To.HexToByteArray()),
135-
// RLP.EncodeElement(transaction.Value.ToByteArray()),
136-
// RLP.EncodeElement(transaction.Data)
137-
// };
138-
139-
// if (signature != null)
140-
// {
141-
// fields.Add(RLP.EncodeElement(signature.V));
142-
// fields.Add(RLP.EncodeElement(signature.R));
143-
// fields.Add(RLP.EncodeElement(signature.S));
144-
// }
145-
// else
146-
// {
147-
// fields.Add(RLP.EncodeElement(chainId.ToByteArray()));
148-
// fields.Add(RLP.EncodeElement(Array.Empty<byte>()));
149-
// fields.Add(RLP.EncodeElement(Array.Empty<byte>()));
150-
// }
151-
152-
// fields.Add(RLP.EncodeElement(chainId.ToByteArray()));
153-
// fields.Add(RLP.EncodeElement(transaction.From.HexToByteArray()));
154-
155-
// // Add meta
156-
// fields.Add(RLP.EncodeElement(transaction.GasPerPubdataByteLimit.ToByteArray()));
157-
// fields.Add(RLP.EncodeList(Array.Empty<byte[]>()));
158-
159-
// if (transaction.PaymasterInput.Length == 0)
160-
// {
161-
// throw new ArgumentException("Empty signatures are not supported!");
162-
// }
163-
// fields.Add(RLP.EncodeElement(transaction.PaymasterInput));
164-
165-
// if (transaction.Paymaster != null)
166-
// {
167-
// fields.Add(RLP.EncodeList(new byte[][] { RLP.EncodeElement(transaction.Paymaster.HexToByteArray()), RLP.EncodeElement(transaction.PaymasterInput) }));
168-
// }
169-
// else
170-
// {
171-
// fields.Add(RLP.EncodeList(Array.Empty<byte[]>()));
172-
// }
110+
private static string SerializeEip712(AccountAbstraction.ZkSyncAATransaction transaction, ECDSASignature signature, string signatureHex, BigInteger chainId)
111+
{
112+
if (chainId == 0)
113+
{
114+
throw new ArgumentException("Chain ID must be provided for EIP712 transactions!");
115+
}
173116

174-
// var rlpEncoded = RLP.EncodeList(fields.ToArray());
175-
// return "0x" + BitConverter.ToString(rlpEncoded).Replace("-", "");
176-
// }
117+
if (string.IsNullOrEmpty(transaction.From))
118+
{
119+
throw new ArgumentException("From address must be provided for EIP712 transactions!");
120+
}
121+
122+
return "0x71"
123+
+ RLP.EncodeList(
124+
transaction.Nonce.ToBytesForRLPEncoding(),
125+
transaction.MaxPriorityFeePerGas.ToBytesForRLPEncoding(),
126+
transaction.MaxFeePerGas.ToBytesForRLPEncoding(),
127+
transaction.GasLimit.ToBytesForRLPEncoding(),
128+
transaction.To.ToBytesForRLPEncoding(),
129+
transaction.Value.ToBytesForRLPEncoding(),
130+
transaction.Data.ToHex().ToBytesForRLPEncoding(),
131+
signature.V.ToHex().ToBytesForRLPEncoding(),
132+
signature.R.ToByteArray().ToHex().ToBytesForRLPEncoding(),
133+
signature.S.ToByteArray().ToHex().ToBytesForRLPEncoding(),
134+
chainId.ToBytesForRLPEncoding(),
135+
transaction.From.ToBytesForRLPEncoding(),
136+
transaction.GasPerPubdataByteLimit.ToBytesForRLPEncoding(),
137+
transaction.FactoryDeps.ToHex().ToBytesForRLPEncoding() ?? Array.Empty<byte>().ToHex().ToBytesForRLPEncoding(),
138+
signatureHex.ToBytesForRLPEncoding(),
139+
transaction.Paymaster.ToBytesForRLPEncoding(),
140+
transaction.PaymasterInput.ToHex().ToBytesForRLPEncoding()
141+
)
142+
.ToHex();
143+
}
177144
}
178145
}

0 commit comments

Comments
 (0)