Repository: wevm/viem (TypeScript)

Issue:
bug: Unable to send transaction with 0 as nonce
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Package Version

0.3.2

### Current Behavior

When using a newly created privateKey with funds directly sent to it using a faucet, I'm unable to send any transaction due to the following error:

```
Request Arguments:
from:   [...]
to:     0xD8Ea779b8FFC1096CA422D40588C4c0641709890
value:  0.001 ETH

Details: rlp: non-canonical integer (leading zero bytes) for uint64, decoding into (types.DynamicFeeTx).Nonce
Version: viem@0.3.2
```

Tested only polygon mumbai

### Expected Behavior

We should be able to send a transaction to the chain even if it's the wallet first transaction

### Steps To Reproduce

1. Generate a new private key
2. Send funds to it using a faucet for example (https://faucet.polygon.technology/)
3. Try to send back funds to the faucet for example results in the error above


### Link to Minimal Reproducible Example (StackBlitz, CodeSandbox, GitHub repo etc.)

https://stackblitz.com/edit/viem-getting-started-xatmau?file=index.ts

### Anything else?

Forcing the transaction to have a different nonce will result in successfully retrieving a hash. The transaction will never make it to the blockchain as it's awaiting a transaction with a `0` as nonce value first if I'm right.

Thank you for the great library !


Discussion: After a bit a digging, looks like if I force `nonce` to be `undefined` instead of `0` in a custom account the transaction will work as expected. My guess is that it's related to something over there : https://github.com/wagmi-dev/viem/blob/630f9cc34e9618041a766ef3e5a110165accbf4a/src/utils/transaction/serializeTransaction.ts#L85

`toHex(nonce = 0)` will produce `0x00` instead of `0x` expected in rlp encoding
This seems to affect more than just the nonce. If you set any of the values to zero the problem is the same.  Changing the check to `nonce ? toHex(nonce) : '0x` should solve the problem.
This will definitely fix the issue but maybe not the right way ? The fact that `toRlp` result in an incorrect value may be the real issue. It should either throw an error or remove leading zeroes, I guess ? 
The rlp/hex encoding is working correctly because if you encode 0 it should always be `0x00` ([reference](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/)). And changing the encoding utils to support this edge case feels like it's out of scope for them. And why i think this would be better suited for the serialize methods to handle this.



Fix (patch):
diff --git a/.changeset/two-ties-sort.md b/.changeset/two-ties-sort.md
new file mode 100644
index 0000000000..e5292d7b0c
--- /dev/null
+++ b/.changeset/two-ties-sort.md
@@ -0,0 +1,5 @@
+---
+"viem": patch
+---
+
+Fixed an issue where `serializeTransaction` was incorrectly encoding zero-ish properties.
diff --git a/src/utils/transaction/serializeTransaction.ts b/src/utils/transaction/serializeTransaction.ts
index cc59c4adef..ee9b8393d4 100644
--- a/src/utils/transaction/serializeTransaction.ts
+++ b/src/utils/transaction/serializeTransaction.ts
@@ -82,14 +82,12 @@ function serializeTransactionEIP1559(
 
   const serializedTransaction = [
     toHex(chainId),
-    typeof nonce !== 'undefined' ? toHex(nonce) : '0x',
-    typeof maxPriorityFeePerGas !== 'undefined'
-      ? toHex(maxPriorityFeePerGas)
-      : '0x',
-    typeof maxFeePerGas !== 'undefined' ? toHex(maxFeePerGas) : '0x',
-    typeof gas !== 'undefined' ? toHex(gas) : '0x',
+    nonce ? toHex(nonce) : '0x',
+    maxPriorityFeePerGas ? toHex(maxPriorityFeePerGas) : '0x',
+    maxFeePerGas ? toHex(maxFeePerGas) : '0x',
+    gas ? toHex(gas) : '0x',
     to ?? '0x',
-    typeof value !== 'undefined' ? toHex(value) : '0x',
+    value ? toHex(value) : '0x',
     data ?? '0x',
     serializedAccessList,
   ]
@@ -120,11 +118,11 @@ function serializeTransactionEIP2930(
 
   const serializedTransaction = [
     toHex(chainId),
-    typeof nonce !== 'undefined' ? toHex(nonce) : '0x',
-    typeof gasPrice !== 'undefined' ? toHex(gasPrice) : '0x',
-    typeof gas !== 'undefined' ? toHex(gas) : '0x',
+    nonce ? toHex(nonce) : '0x',
+    gasPrice ? toHex(gasPrice) : '0x',
+    gas ? toHex(gas) : '0x',
     to ?? '0x',
-    typeof value !== 'undefined' ? toHex(value) : '0x',
+    value ? toHex(value) : '0x',
     data ?? '0x',
     serializedAccessList,
   ]
@@ -151,11 +149,11 @@ function serializeTransactionLegacy(
   assertTransactionLegacy(transaction)
 
   let serializedTransaction = [
-    typeof nonce !== 'undefined' ? toHex(nonce) : '0x',
-    typeof gasPrice !== 'undefined' ? toHex(gasPrice) : '0x',
-    typeof gas !== 'undefined' ? toHex(gas) : '0x',
+    nonce ? toHex(nonce) : '0x',
+    gasPrice ? toHex(gasPrice) : '0x',
+    gas ? toHex(gas) : '0x',
     to ?? '0x',
-    typeof value !== 'undefined' ? toHex(value) : '0x',
+    value ? toHex(value) : '0x',
     data ?? '0x',
   ]