diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d732a6bf29..322e3942c2 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -179,7 +179,7 @@ jobs:
uses: hiero-ledger/hiero-solo-action@dd0048139ef1e40fd6067f01bf94eb42a67294f4 # v0.15
with:
installMirrorNode: true
- hieroVersion: v0.69.0-alpha.1
+ hieroVersion: v0.70
- name: Build SDK
run: ./gradlew assemble
@@ -302,7 +302,7 @@ jobs:
uses: hiero-ledger/hiero-solo-action@dd0048139ef1e40fd6067f01bf94eb42a67294f4 # v0.15
with:
installMirrorNode: true
- hieroVersion: v0.69.0-alpha.1
+ hieroVersion: v0.70
- name: Build SDK
run: ./gradlew assemble
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransaction.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransaction.java
index df0a53fb0e..d7c0054fac 100644
--- a/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransaction.java
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransaction.java
@@ -59,7 +59,7 @@ public byte[] getEthereumData() {
}
/**
- * Sets the raw Ethereum transaction (RLP encoded type 0, 1, and 2). Complete
+ * Sets the raw Ethereum transaction (RLP encoded type 0, 1, 2 and 4). Complete
* unless the callDataFileId is set.
*
* @param ethereumData raw ethereum transaction bytes
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionData.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionData.java
index cec713e552..9d4ea45c2b 100644
--- a/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionData.java
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionData.java
@@ -24,7 +24,13 @@ static EthereumTransactionData fromBytes(byte[] bytes) {
if (rlpItem.isList()) {
return EthereumTransactionDataLegacy.fromBytes(bytes);
} else {
- return EthereumTransactionDataEip1559.fromBytes(bytes);
+ var typeByte = rlpItem.asByte();
+
+ return switch (typeByte) {
+ case 0x02 -> EthereumTransactionDataEip1559.fromBytes(bytes);
+ case 0x04 -> EthereumTransactionDataEip7702.fromBytes(bytes);
+ default -> throw new IllegalArgumentException("rlp type byte " + typeByte + "is not supported");
+ };
}
}
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionDataEip7702.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionDataEip7702.java
new file mode 100644
index 0000000000..0949f5146b
--- /dev/null
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/EthereumTransactionDataEip7702.java
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: Apache-2.0
+package com.hedera.hashgraph.sdk;
+
+import com.esaulpaugh.headlong.rlp.RLPDecoder;
+import com.esaulpaugh.headlong.rlp.RLPEncoder;
+import com.esaulpaugh.headlong.rlp.RLPItem;
+import com.esaulpaugh.headlong.util.Integers;
+import com.google.common.base.MoreObjects;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.bouncycastle.util.encoders.Hex;
+
+/**
+ * The ethereum transaction data, in the format defined in
+ * EIP-7702
+ */
+public class EthereumTransactionDataEip7702 extends EthereumTransactionData {
+
+ /**
+ * ID of the chain.
+ */
+ public byte[] chainId;
+
+ /**
+ * Transaction's nonce.
+ */
+ public byte[] nonce;
+
+ /**
+ * An 'optional' additional fee in Ethereum that is paid directly to miners in order to incentivize them to include
+ * your transaction in a block. Not used in Hedera.
+ */
+ public byte[] maxPriorityGas;
+
+ /**
+ * The maximum amount, in tinybars, that the payer of the hedera transaction is willing to pay to complete the
+ * transaction.
+ */
+ public byte[] maxGas;
+
+ /**
+ * The amount of gas available for the transaction.
+ */
+ public byte[] gasLimit;
+
+ /**
+ * The receiver of the transaction.
+ */
+ public byte[] to;
+
+ /**
+ * The transaction value.
+ */
+ public byte[] value;
+
+ /**
+ * Specifies an array of addresses and storage keys that the transaction plans to access.
+ */
+ public List accessList;
+
+ /**
+ * The list of delegation authorizations.
+ */
+ public List authorizationList;
+
+ /**
+ * Recovery parameter used to ease the signature verification.
+ */
+ public byte[] recoveryId;
+
+ /**
+ * The R value of the signature.
+ */
+ public byte[] r;
+
+ /**
+ * The S value of the signature.
+ */
+ public byte[] s;
+
+ EthereumTransactionDataEip7702(
+ HeaderData headerData,
+ byte[] callData,
+ List accessList,
+ List authorizationList,
+ SignatureData signatureData) {
+ super(callData);
+
+ this.chainId = headerData.chainId();
+ this.nonce = headerData.nonce();
+ this.maxPriorityGas = headerData.maxPriorityGas();
+ this.maxGas = headerData.maxGas();
+ this.gasLimit = headerData.gasLimit();
+ this.to = headerData.to();
+ this.value = headerData.value();
+ this.accessList = accessList;
+ this.authorizationList = authorizationList;
+ this.recoveryId = signatureData.recoveryId();
+ this.r = signatureData.r();
+ this.s = signatureData.s();
+ }
+
+ /**
+ * Convert a byte array to an ethereum transaction data.
+ *
+ * @param bytes the byte array
+ * @return the ethereum transaction data
+ */
+ public static EthereumTransactionDataEip7702 fromBytes(byte[] bytes) {
+ var decoder = RLPDecoder.RLP_STRICT.sequenceIterator(bytes);
+ var rlpItem = decoder.next();
+
+ // typed transaction?
+ byte typeByte = rlpItem.asByte();
+ if (typeByte != 4) {
+ throw new IllegalArgumentException("rlp type byte " + typeByte + " is not supported");
+ }
+ rlpItem = decoder.next();
+ if (!rlpItem.isList()) {
+ throw new IllegalArgumentException("expected RLP element list");
+ }
+ List rlpList = rlpItem.asRLPList().elements();
+ if (rlpList.size() != 13) {
+ throw new IllegalArgumentException("expected 13 RLP encoded elements, found " + rlpList.size());
+ }
+
+ var accessList = new ArrayList();
+ for (var accessListItem : rlpList.get(8).asRLPList().elements()) {
+ accessList.add(accessListItem.data());
+ }
+
+ var authorizationList = new ArrayList();
+ for (var authorizationTuple : rlpList.get(9).asRLPList().elements()) {
+ var tupleElements = authorizationTuple.asRLPList().elements();
+ if (tupleElements.size() != 6) {
+ throw new IllegalArgumentException("invalid authorization list entry: must have 6 elements");
+ }
+ authorizationList.add(new AuthorizationTuple(
+ tupleElements.get(0).data(),
+ tupleElements.get(1).data(),
+ tupleElements.get(2).data(),
+ tupleElements.get(3).data(),
+ tupleElements.get(4).data(),
+ tupleElements.get(5).data()));
+ }
+
+ var headerData = new HeaderData(
+ rlpList.get(0).data(),
+ rlpList.get(1).data(),
+ rlpList.get(2).data(),
+ rlpList.get(3).data(),
+ rlpList.get(4).data(),
+ rlpList.get(5).data(),
+ rlpList.get(6).data());
+
+ var signatureData = new SignatureData(
+ rlpList.get(10).data(), rlpList.get(11).data(), rlpList.get(12).data());
+
+ return new EthereumTransactionDataEip7702(
+ headerData, rlpList.get(7).data(), accessList, authorizationList, signatureData);
+ }
+
+ public byte[] toBytes() {
+ List