Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/main/java/com/iexec/commons/poco/chain/SignerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package com.iexec.commons.poco.chain;

import com.iexec.commons.poco.eip712.EIP712Domain;
import com.iexec.commons.poco.eip712.EIP712Entity;
import com.iexec.commons.poco.eip712.EIP712TypedData;
import com.iexec.commons.poco.order.Order;
import com.iexec.commons.poco.security.Signature;
import com.iexec.commons.poco.utils.BytesUtils;
import com.iexec.commons.poco.utils.EthAddress;
Expand Down Expand Up @@ -111,6 +114,10 @@ public Signature signMessageHash(String messageHash) {
return SignatureUtils.signMessageHashAndGetSignature(messageHash, credentials.getEcKeyPair());
}

/**
* @deprecated use signTypedDataForDomain instead
*/
@Deprecated(forRemoval = true)
public String signEIP712Entity(EIP712Entity<?> eip712Entity) {
final String signature = eip712Entity.signMessage(credentials.getEcKeyPair());
if (StringUtils.isEmpty(signature)) {
Expand All @@ -120,6 +127,23 @@ public String signEIP712Entity(EIP712Entity<?> eip712Entity) {
return signature;
}

/**
* Hashes and signs structured type data following EIP-712
*
* @param typedData structured data implementing {@link EIP712TypedData} to hash and sign
* @param domain EIP712 domain describing the target for which the data is hashed and signed
* @return a valid signature
* @see <a href="https://eips.ethereum.org/EIPS/eip-712">EIP-712</a>
*/
public String signTypedDataForDomain(final EIP712TypedData typedData, final EIP712Domain domain) {
return typedData.sign(credentials.getEcKeyPair(), domain);
}

public Order signOrderForDomain(final Order order, final EIP712Domain domain) {
final String sig = signTypedDataForDomain(order, domain);
return order.withSignature(sig);
}

/**
* Builds an authorization token for given {@link EIP712Entity}.
* <p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,10 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @deprecated implements {@code EIP712TypedData} interface instead
*/
@Deprecated(forRemoval = true)
@Slf4j
@NoArgsConstructor
public abstract class EIP712Entity<M> implements EIP712<M> {
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/iexec/commons/poco/eip712/EIP712TypedData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.iexec.commons.poco.eip712;

import com.iexec.commons.poco.utils.HashUtils;
import com.iexec.commons.poco.utils.SignatureUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.crypto.ECKeyPair;

public interface EIP712TypedData {
Logger log = LoggerFactory.getLogger(EIP712TypedData.class);

default String computeHash(final EIP712Domain domain) {
final String domainSeparator = domain.getDomainSeparator();
final String messageHash = computeMessageHash();
final String hash = HashUtils.concatenateAndHash("0x1901", domainSeparator, messageHash);
if (log.isDebugEnabled()) {
log.debug("domainSeparator {}", domainSeparator);
log.debug("messageHash {}", messageHash);
log.debug("hash {}", hash);
}
return hash;
}

String computeMessageHash();

default String sign(final ECKeyPair ecKeyPair, final EIP712Domain domain) {
return SignatureUtils.signAsString(computeHash(domain), ecKeyPair);
}
}
28 changes: 27 additions & 1 deletion src/main/java/com/iexec/commons/poco/order/AppOrder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,18 +19,25 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.iexec.commons.poco.contract.generated.IexecHubContract;
import com.iexec.commons.poco.eip712.EIP712Utils;
import com.iexec.commons.poco.utils.HashUtils;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.stream.Stream;

@Slf4j
@Value
@EqualsAndHashCode(callSuper = true)
@JsonDeserialize(builder = AppOrder.AppOrderBuilder.class)
public class AppOrder extends Order {

private static final String EIP712_TYPE = "AppOrder(address app,uint256 appprice,uint256 volume,bytes32 tag,address datasetrestrict,address workerpoolrestrict,address requesterrestrict,bytes32 salt)";

String app;
BigInteger appprice;
String datasetrestrict;
Expand Down Expand Up @@ -70,6 +77,25 @@ public AppOrder withSignature(String signature) {
);
}

// region EIP-712
public String computeMessageHash() {
final String[] encodedValues = Stream.of(EIP712_TYPE, app, appprice, volume, tag, datasetrestrict, workerpoolrestrict, requesterrestrict, salt)
.map(EIP712Utils::encodeData)
.toArray(String[]::new);
if (log.isDebugEnabled()) {
log.debug("{}", EIP712_TYPE);
for (String value : encodedValues) {
log.debug("{}", value);
}
}
return HashUtils.concatenateAndHash(encodedValues);
}
// endregion

/**
* @deprecated no more used
*/
@Deprecated(forRemoval = true)
public IexecHubContract.AppOrder toHubContract() {
return new IexecHubContract.AppOrder(
this.app,
Expand Down
28 changes: 27 additions & 1 deletion src/main/java/com/iexec/commons/poco/order/DatasetOrder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,18 +19,25 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.iexec.commons.poco.contract.generated.IexecHubContract;
import com.iexec.commons.poco.eip712.EIP712Utils;
import com.iexec.commons.poco.utils.HashUtils;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.stream.Stream;

@Slf4j
@Value
@EqualsAndHashCode(callSuper = true)
@JsonDeserialize(builder = DatasetOrder.DatasetOrderBuilder.class)
public class DatasetOrder extends Order {

private static final String EIP712_TYPE = "DatasetOrder(address dataset,uint256 datasetprice,uint256 volume,bytes32 tag,address apprestrict,address workerpoolrestrict,address requesterrestrict,bytes32 salt)";

String dataset;
BigInteger datasetprice;
String apprestrict;
Expand Down Expand Up @@ -69,6 +76,25 @@ public DatasetOrder withSignature(String signature) {
);
}

// region EIP-712
public String computeMessageHash() {
final String[] encodedValues = Stream.of(EIP712_TYPE, dataset, datasetprice, volume, tag, apprestrict, workerpoolrestrict, requesterrestrict, salt)
.map(EIP712Utils::encodeData)
.toArray(String[]::new);
if (log.isDebugEnabled()) {
log.debug("{}", EIP712_TYPE);
for (String value : encodedValues) {
log.debug("{}", value);
}
}
return HashUtils.concatenateAndHash(encodedValues);
}
// endregion

/**
* @deprecated no more used
*/
@Deprecated(forRemoval = true)
public IexecHubContract.DatasetOrder toHubContract() {
return new IexecHubContract.DatasetOrder(
this.dataset,
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/iexec/commons/poco/order/Order.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,15 +17,18 @@
package com.iexec.commons.poco.order;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.iexec.commons.poco.eip712.EIP712TypedData;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;

@Slf4j
@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class Order {
public abstract class Order implements EIP712TypedData {

protected final BigInteger volume;
protected final String tag;
Expand Down
28 changes: 27 additions & 1 deletion src/main/java/com/iexec/commons/poco/order/RequestOrder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,18 +19,25 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.iexec.commons.poco.contract.generated.IexecHubContract;
import com.iexec.commons.poco.eip712.EIP712Utils;
import com.iexec.commons.poco.utils.HashUtils;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.stream.Stream;

@Slf4j
@Value
@EqualsAndHashCode(callSuper = true)
@JsonDeserialize(builder = RequestOrder.RequestOrderBuilder.class)
public class RequestOrder extends Order {

private static final String EIP712_TYPE = "RequestOrder(address app,uint256 appmaxprice,address dataset,uint256 datasetmaxprice,address workerpool,uint256 workerpoolmaxprice,address requester,uint256 volume,bytes32 tag,uint256 category,uint256 trust,address beneficiary,address callback,string params,bytes32 salt)";

String app;
BigInteger appmaxprice;
String dataset;
Expand Down Expand Up @@ -92,6 +99,25 @@ public RequestOrder withSignature(String signature) {
);
}

// region EIP-712
public String computeMessageHash() {
final String[] encodedValues = Stream.of(EIP712_TYPE, app, appmaxprice, dataset, datasetmaxprice, workerpool, workerpoolmaxprice, requester, volume, tag, category, trust, beneficiary, callback, params, salt)
.map(EIP712Utils::encodeData)
.toArray(String[]::new);
if (log.isDebugEnabled()) {
log.debug("{}", EIP712_TYPE);
for (String value : encodedValues) {
log.debug("{}", value);
}
}
return HashUtils.concatenateAndHash(encodedValues);
}
// endregion

/**
* @deprecated no more used
*/
@Deprecated(forRemoval = true)
public IexecHubContract.RequestOrder toHubContract() {
return new IexecHubContract.RequestOrder(
this.app,
Expand Down
30 changes: 27 additions & 3 deletions src/main/java/com/iexec/commons/poco/order/WorkerpoolOrder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,20 +19,25 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.iexec.commons.poco.contract.generated.IexecHubContract;
import com.iexec.commons.poco.eip712.EIP712Utils;
import com.iexec.commons.poco.utils.HashUtils;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.stream.Stream;

@Slf4j
@Value
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@JsonDeserialize(builder = WorkerpoolOrder.WorkerpoolOrderBuilder.class)
public class WorkerpoolOrder extends Order {

private static final String EIP712_TYPE = "WorkerpoolOrder(address workerpool,uint256 workerpoolprice,uint256 volume,bytes32 tag,uint256 category,uint256 trust,address apprestrict,address datasetrestrict,address requesterrestrict,bytes32 salt)";

String workerpool;
BigInteger workerpoolprice;
BigInteger trust;
Expand Down Expand Up @@ -78,6 +83,25 @@ public WorkerpoolOrder withSignature(String signature) {
);
}

// region EIP-712
public String computeMessageHash() {
final String[] encodedValues = Stream.of(EIP712_TYPE, workerpool, workerpoolprice, volume, tag, category, trust, apprestrict, datasetrestrict, requesterrestrict, salt)
.map(EIP712Utils::encodeData)
.toArray(String[]::new);
if (log.isDebugEnabled()) {
log.debug("{}", EIP712_TYPE);
for (String value : encodedValues) {
log.debug("{}", value);
}
}
return HashUtils.concatenateAndHash(encodedValues);
}
// endregion

/**
* @deprecated no more used
*/
@Deprecated(forRemoval = true)
public IexecHubContract.WorkerpoolOrder toHubContract() {
return new IexecHubContract.WorkerpoolOrder(
this.workerpool,
Expand Down
Loading