From 006d4d8abe474f82577c16b4b0625e97705e263e Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:02:21 +0200 Subject: [PATCH 01/11] fix!: remove ENS support BREAKING CHANGE: ENS names are no longer accepted as addresses; all address fields now require a plain Ethereum address; drops the AddressOrENS type in favour of Address. --- .../sdk/src/lib/IExecDataProtectorModule.ts | 6 +- .../IExecDataProtectorCore.ts | 1 - .../lib/dataProtectorCore/getGrantedAccess.ts | 8 +-- .../lib/dataProtectorCore/getProtectedData.ts | 15 ++-- .../src/lib/dataProtectorCore/grantAccess.ts | 17 ++--- .../dataProtectorCore/prepareBulkRequest.ts | 6 +- .../dataProtectorCore/processBulkRequest.ts | 6 +- .../dataProtectorCore/processProtectedData.ts | 9 ++- .../lib/dataProtectorCore/revokeAllAccess.ts | 8 +-- .../getDataProtectorCoreContract.ts | 4 +- .../smartContract/getWhitelistContract.ts | 4 +- .../dataProtectorCore/transferOwnership.ts | 6 +- packages/sdk/src/lib/types/commonTypes.ts | 13 +--- packages/sdk/src/lib/types/coreTypes.ts | 69 +++++++++---------- packages/sdk/src/lib/types/graphQLTypes.ts | 4 +- packages/sdk/src/lib/types/internalTypes.ts | 6 +- packages/sdk/src/utils/resolveENS.ts | 17 ----- packages/sdk/src/utils/validators.ts | 11 --- .../getProtectedData.test.ts | 22 ------ .../getGrantedAccess.test.ts | 6 +- .../getProtectedData.test.ts | 34 +-------- .../dataProtectorCore/grantAccess.test.ts | 32 +-------- .../prepareBulkRequest.test.ts | 4 +- .../processBulkRequest.test.ts | 4 +- .../processProtectedData.test.ts | 6 +- .../dataProtectorCore/revokeAllAccess.test.ts | 6 +- .../transferOwnership.test.ts | 4 +- .../sdk/tests/unit/utils/validators.test.ts | 60 ---------------- 28 files changed, 99 insertions(+), 289 deletions(-) delete mode 100644 packages/sdk/src/utils/resolveENS.ts diff --git a/packages/sdk/src/lib/IExecDataProtectorModule.ts b/packages/sdk/src/lib/IExecDataProtectorModule.ts index 343aa4c4e..4098aa92b 100644 --- a/packages/sdk/src/lib/IExecDataProtectorModule.ts +++ b/packages/sdk/src/lib/IExecDataProtectorModule.ts @@ -7,7 +7,7 @@ import { } from '../config/config.js'; import { getChainIdFromProvider } from '../utils/getChainId.js'; import { - AddressOrENS, + Address, DataProtectorConfigOptions, Web3SignerProvider, } from './types/index.js'; @@ -20,7 +20,7 @@ type EthersCompatibleProvider = | string; interface IExecDataProtectorResolvedConfig { - dataprotectorContractAddress: AddressOrENS; + dataprotectorContractAddress: Address; graphQLClient: GraphQLClient; pocoSubgraphClient: GraphQLClient; ipfsNode: string; @@ -30,7 +30,7 @@ interface IExecDataProtectorResolvedConfig { } abstract class IExecDataProtectorModule { - protected dataprotectorContractAddress!: AddressOrENS; + protected dataprotectorContractAddress!: Address; protected graphQLClient!: GraphQLClient; diff --git a/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts b/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts index 20208430b..b7f3e88d2 100644 --- a/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts +++ b/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts @@ -122,7 +122,6 @@ class IExecDataProtectorCore extends IExecDataProtectorModule { await this.init(); return getProtectedData({ ...args, - iexec: this.iexec, graphQLClient: this.graphQLClient, }); } diff --git a/packages/sdk/src/lib/dataProtectorCore/getGrantedAccess.ts b/packages/sdk/src/lib/dataProtectorCore/getGrantedAccess.ts index 25bcc9537..652e8d3fe 100644 --- a/packages/sdk/src/lib/dataProtectorCore/getGrantedAccess.ts +++ b/packages/sdk/src/lib/dataProtectorCore/getGrantedAccess.ts @@ -1,7 +1,7 @@ import { WorkflowError, handleIfProtocolError } from '../../utils/errors.js'; import { formatGrantedAccess } from '../../utils/formatGrantedAccess.js'; import { - addressOrEnsSchema, + addressSchema, booleanSchema, numberBetweenSchema, positiveNumberSchema, @@ -23,13 +23,13 @@ export const getGrantedAccess = async ({ pageSize, bulkOnly = false, }: IExecConsumer & GetGrantedAccessParams): Promise => { - const vProtectedData = addressOrEnsSchema() + const vProtectedData = addressSchema() .label('protectedData') .validateSync(protectedData); - const vAuthorizedApp = addressOrEnsSchema() + const vAuthorizedApp = addressSchema() .label('authorizedApp') .validateSync(authorizedApp); - const vAuthorizedUser = addressOrEnsSchema() + const vAuthorizedUser = addressSchema() .label('authorizedUser') .validateSync(authorizedUser); const vIsUserStrict = booleanSchema() diff --git a/packages/sdk/src/lib/dataProtectorCore/getProtectedData.ts b/packages/sdk/src/lib/dataProtectorCore/getProtectedData.ts index 98222773f..c320efd71 100644 --- a/packages/sdk/src/lib/dataProtectorCore/getProtectedData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/getProtectedData.ts @@ -5,9 +5,8 @@ import { } from '../../utils/data.js'; import { ValidationError, WorkflowError } from '../../utils/errors.js'; import { getMultiaddrAsString } from '../../utils/getMultiaddrAsString.js'; -import { resolveENS } from '../../utils/resolveENS.js'; import { - addressOrEnsSchema, + addressSchema, numberBetweenSchema, positiveNumberSchema, throwIfMissing, @@ -18,10 +17,9 @@ import { ProtectedData, SearchableDataSchema, } from '../types/index.js'; -import { IExecConsumer, SubgraphConsumer } from '../types/internalTypes.js'; +import { SubgraphConsumer } from '../types/internalTypes.js'; export const getProtectedData = async ({ - iexec = throwIfMissing(), graphQLClient = throwIfMissing(), protectedDataAddress, requiredSchema = {}, @@ -29,13 +27,11 @@ export const getProtectedData = async ({ createdAfterTimestamp, page = 0, pageSize = 1000, -}: GetProtectedDataParams & IExecConsumer & SubgraphConsumer): Promise< - ProtectedData[] -> => { +}: GetProtectedDataParams & SubgraphConsumer): Promise => { const vCreatedAfterTimestamp = positiveNumberSchema() .label('createdAfterTimestamp') .validateSync(createdAfterTimestamp); - const vProtectedDataAddress = addressOrEnsSchema() + const vProtectedDataAddress = addressSchema() .label('protectedDataAddress') .validateSync(protectedDataAddress); @@ -50,8 +46,7 @@ export const getProtectedData = async ({ const vPageSize = numberBetweenSchema(10, 1000) .label('pageSize') .validateSync(pageSize); - let vOwner = addressOrEnsSchema().label('owner').validateSync(owner); - vOwner = await resolveENS(iexec, vOwner); + const vOwner = addressSchema().label('owner').validateSync(owner); try { const start = vPage * vPageSize; diff --git a/packages/sdk/src/lib/dataProtectorCore/grantAccess.ts b/packages/sdk/src/lib/dataProtectorCore/grantAccess.ts index 7c4a9b129..3a29e7667 100644 --- a/packages/sdk/src/lib/dataProtectorCore/grantAccess.ts +++ b/packages/sdk/src/lib/dataProtectorCore/grantAccess.ts @@ -9,9 +9,8 @@ import { } from '../../utils/errors.js'; import { formatGrantedAccess } from '../../utils/formatGrantedAccess.js'; import { - addressOrEnsSchema, + addressSchema, booleanSchema, - isEnsTest, positiveIntegerStringSchema, positiveStrictIntegerStringSchema, throwIfMissing, @@ -37,15 +36,15 @@ export const grantAccess = async ({ allowBulk = false, onStatusUpdate = () => {}, }: IExecConsumer & GrantAccessParams): Promise => { - const vProtectedData = addressOrEnsSchema() + const vProtectedData = addressSchema() .required() .label('protectedData') .validateSync(protectedData); - let vAuthorizedApp = addressOrEnsSchema() + const vAuthorizedApp = addressSchema() .required() .label('authorizedApp') .validateSync(authorizedApp); - const vAuthorizedUser = addressOrEnsSchema() + const vAuthorizedUser = addressSchema() .label('authorizedUser') .validateSync(authorizedUser); let vPricePerAccess = positiveIntegerStringSchema() @@ -79,14 +78,6 @@ export const grantAccess = async ({ vNumberOfAccess = DATASET_INFINITE_VOLUME.toString(); } - if (vAuthorizedApp && isEnsTest(vAuthorizedApp)) { - const resolved = await iexec.ens.resolveName(vAuthorizedApp); - if (!resolved) { - throw new ValidationError('authorizedApp ENS name is not valid'); - } - vAuthorizedApp = resolved.toLowerCase(); - } - if (vAuthorizedApp === ZeroAddress) { throw Error( `Forbidden to use ${ZeroAddress} as authorizedApp, this would give access to any app` diff --git a/packages/sdk/src/lib/dataProtectorCore/prepareBulkRequest.ts b/packages/sdk/src/lib/dataProtectorCore/prepareBulkRequest.ts index f999b9b2b..8eedbc66d 100644 --- a/packages/sdk/src/lib/dataProtectorCore/prepareBulkRequest.ts +++ b/packages/sdk/src/lib/dataProtectorCore/prepareBulkRequest.ts @@ -16,7 +16,7 @@ import { formatPemPublicKeyForSMS, } from '../../utils/rsa.js'; import { - addressOrEnsSchema, + addressSchema, booleanSchema, positiveNumberSchema, secretsSchema, @@ -51,7 +51,7 @@ export const prepareBulkRequest = async ({ onStatusUpdate = () => {}, }: IExecConsumer & PrepareBulkRequestParams): Promise => { - const vApp = addressOrEnsSchema().required().label('app').validateSync(app); + const vApp = addressSchema().required().label('app').validateSync(app); const vMaxProtectedDataPerTask = positiveNumberSchema() .label('maxProtectedDataPerTask') .validateSync(maxProtectedDataPerTask); @@ -66,7 +66,7 @@ export const prepareBulkRequest = async ({ .validateSync(inputFiles); const vArgs = stringSchema().label('args').validateSync(args); const vSecrets = secretsSchema().label('secrets').validateSync(secrets); - const vWorkerpool = addressOrEnsSchema() + const vWorkerpool = addressSchema() .default(NULL_ADDRESS) .label('workerpool') .validateSync(workerpool); diff --git a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts index 3cbad9e61..b3efef678 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts @@ -11,7 +11,7 @@ import { filterWorkerpoolOrders, } from '../../utils/processProtectedData.models.js'; import { - addressOrEnsSchema, + addressSchema, booleanSchema, bulkRequestSchema, stringSchema, @@ -62,14 +62,14 @@ export const processBulkRequest = async < .label('bulkRequest') .required() .validateSync(bulkRequest) as BulkRequest; // Type assertion after validation - const vWorkerpool = addressOrEnsSchema() + const vWorkerpool = addressSchema() .default(defaultWorkerpool) // Default workerpool if none is specified .label('workerpool') .validateSync(workerpool); const vUseVoucher = booleanSchema() .label('useVoucher') .validateSync(useVoucher); - const vVoucherOwner = addressOrEnsSchema() + const vVoucherOwner = addressSchema() .label('voucherOwner') .validateSync(voucherOwner); const vWaitForResult = booleanSchema() diff --git a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts index 4e78934e7..dfbb00f19 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts @@ -21,7 +21,6 @@ import { formatPemPublicKeyForSMS, } from '../../utils/rsa.js'; import { - addressOrEnsSchema, addressSchema, booleanSchema, positiveNumberSchema, @@ -73,11 +72,11 @@ export const processProtectedData = async < }: IExecConsumer & DefaultWorkerpoolConsumer & Params): Promise< ProcessProtectedDataResponse > => { - const vProtectedData = addressOrEnsSchema() + const vProtectedData = addressSchema() .required() .label('protectedData') .validateSync(protectedData); - const vApp = addressOrEnsSchema() + const vApp = addressSchema() .required() .label('authorizedApp') .validateSync(app); @@ -99,14 +98,14 @@ export const processProtectedData = async < .validateSync(inputFiles); const vArgs = stringSchema().label('args').validateSync(args); const vSecrets = secretsSchema().label('secrets').validateSync(secrets); - const vWorkerpool = addressOrEnsSchema() + const vWorkerpool = addressSchema() .default(defaultWorkerpool) // Default workerpool if none is specified .label('workerpool') .validateSync(workerpool); const vUseVoucher = booleanSchema() .label('useVoucher') .validateSync(useVoucher); - const vVoucherOwner = addressOrEnsSchema() + const vVoucherOwner = addressSchema() .label('voucherOwner') .validateSync(voucherOwner); const vEncryptResult = booleanSchema() diff --git a/packages/sdk/src/lib/dataProtectorCore/revokeAllAccess.ts b/packages/sdk/src/lib/dataProtectorCore/revokeAllAccess.ts index bc9c88b2e..2cc7e7bfa 100644 --- a/packages/sdk/src/lib/dataProtectorCore/revokeAllAccess.ts +++ b/packages/sdk/src/lib/dataProtectorCore/revokeAllAccess.ts @@ -1,6 +1,6 @@ import { WorkflowError } from '../../utils/errors.js'; import { - addressOrEnsSchema, + addressSchema, throwIfMissing, validateOnStatusUpdateCallback, } from '../../utils/validators.js'; @@ -21,14 +21,14 @@ export const revokeAllAccess = async ({ authorizedUser, onStatusUpdate = () => {}, }: IExecConsumer & RevokeAllAccessParams): Promise => { - const vProtectedData = addressOrEnsSchema() + const vProtectedData = addressSchema() .required() .label('protectedData') .validateSync(protectedData); - const vAuthorizedApp = addressOrEnsSchema() + const vAuthorizedApp = addressSchema() .label('authorizedApp') .validateSync(authorizedApp); - const vAuthorizedUser = addressOrEnsSchema() + const vAuthorizedUser = addressSchema() .label('authorizedUser') .validateSync(authorizedUser); const vOnStatusUpdate = diff --git a/packages/sdk/src/lib/dataProtectorCore/smartContract/getDataProtectorCoreContract.ts b/packages/sdk/src/lib/dataProtectorCore/smartContract/getDataProtectorCoreContract.ts index c95b82484..aa0d93676 100644 --- a/packages/sdk/src/lib/dataProtectorCore/smartContract/getDataProtectorCoreContract.ts +++ b/packages/sdk/src/lib/dataProtectorCore/smartContract/getDataProtectorCoreContract.ts @@ -2,11 +2,11 @@ import { Contract } from 'ethers'; import { IExec } from 'iexec'; import { ABI } from '../../../../generated/abis/core/interfaces/IDataProtector.sol/IDataProtector.js'; import { IDataProtector } from '../../../../generated/typechain/interfaces/IDataProtector.js'; -import { AddressOrENS } from '../../types/commonTypes.js'; +import { Address } from '../../types/commonTypes.js'; export async function getDataProtectorCoreContract( iexec: IExec, - contractAddress: AddressOrENS + contractAddress: Address ): Promise { const { signer } = await iexec.config.resolveContractsClient(); return new Contract(contractAddress, ABI).connect(signer) as IDataProtector; diff --git a/packages/sdk/src/lib/dataProtectorCore/smartContract/getWhitelistContract.ts b/packages/sdk/src/lib/dataProtectorCore/smartContract/getWhitelistContract.ts index 3d48a7e03..74240e7fc 100644 --- a/packages/sdk/src/lib/dataProtectorCore/smartContract/getWhitelistContract.ts +++ b/packages/sdk/src/lib/dataProtectorCore/smartContract/getWhitelistContract.ts @@ -2,11 +2,11 @@ import { Contract } from 'ethers'; import { IExec } from 'iexec'; import { ABI } from '../../../../generated/abis/core/registry/ERC734.sol/ERC734.js'; import { ERC734 } from '../../../../generated/typechain/registry/ERC734.js'; -import { AddressOrENS } from '../../types/commonTypes.js'; +import { Address } from '../../types/commonTypes.js'; export async function getWhitelistContract( iexec: IExec, - contractAddress: AddressOrENS + contractAddress: Address ): Promise { const { signer } = await iexec.config.resolveContractsClient(); return new Contract(contractAddress, ABI).connect(signer) as ERC734; diff --git a/packages/sdk/src/lib/dataProtectorCore/transferOwnership.ts b/packages/sdk/src/lib/dataProtectorCore/transferOwnership.ts index 04ab37bc5..e633c49a4 100644 --- a/packages/sdk/src/lib/dataProtectorCore/transferOwnership.ts +++ b/packages/sdk/src/lib/dataProtectorCore/transferOwnership.ts @@ -1,5 +1,5 @@ import { WorkflowError } from '../../utils/errors.js'; -import { addressOrEnsSchema, throwIfMissing } from '../../utils/validators.js'; +import { addressSchema, throwIfMissing } from '../../utils/validators.js'; import { TransferParams, TransferResponse } from '../types/index.js'; import { IExecConsumer } from '../types/internalTypes.js'; @@ -8,11 +8,11 @@ export const transferOwnership = async ({ protectedData, newOwner, }: IExecConsumer & TransferParams): Promise => { - const vProtectedData = addressOrEnsSchema() + const vProtectedData = addressSchema() .required() .label('protectedData') .validateSync(protectedData); - const vNewOwner = addressOrEnsSchema() + const vNewOwner = addressSchema() .required() .label('newOwner') .validateSync(newOwner); diff --git a/packages/sdk/src/lib/types/commonTypes.ts b/packages/sdk/src/lib/types/commonTypes.ts index cef296bd9..1f2993330 100644 --- a/packages/sdk/src/lib/types/commonTypes.ts +++ b/packages/sdk/src/lib/types/commonTypes.ts @@ -8,17 +8,10 @@ export type { Taskid } from 'iexec'; * Common Types * ***************************************************************************/ -type ENS = string; - export type Address = string; export type Web3SignerProvider = EnhancedWallet; -/** - * ethereum address or ENS name (Ethereum Name Service) - */ -export type AddressOrENS = Address | ENS; - export type OnStatusUpdateFn = (params: { title: T; isDone: boolean; @@ -31,11 +24,11 @@ export type OnStatusUpdateFn = (params: { */ export type DataProtectorConfigOptions = { /** - * The Ethereum contract address or ENS (Ethereum Name Service) for dataProtector smart contract. + * The Ethereum contract address for dataProtector smart contract. * If not provided, the default dataProtector contract address will be used. * @default{@link DEFAULT_CONTRACT_ADDRESS} */ - dataprotectorContractAddress?: AddressOrENS; + dataprotectorContractAddress?: Address; /** * The subgraph URL for querying data. @@ -119,5 +112,5 @@ export type MatchOptions = { }; export type DefaultWorkerpoolConsumer = { - defaultWorkerpool: AddressOrENS; + defaultWorkerpool: Address; }; diff --git a/packages/sdk/src/lib/types/coreTypes.ts b/packages/sdk/src/lib/types/coreTypes.ts index 314b18c0a..539d2e772 100644 --- a/packages/sdk/src/lib/types/coreTypes.ts +++ b/packages/sdk/src/lib/types/coreTypes.ts @@ -1,6 +1,5 @@ import { Address, - AddressOrENS, DataSchema, OnStatusUpdateFn, SearchableDataSchema, @@ -104,26 +103,26 @@ export type ProtectedDataWithSecretProps = ProtectedData & // ---------------------GetGrantedAccess Types------------------------------------ export type GetGrantedAccessParams = { /** - * Protected Data address or ENS + * Protected Data address * * Default fetch for any protectedData */ - protectedData?: AddressOrENS; + protectedData?: Address; /** - * Address or ENS of the app authorized to use the `protectedData` + * Address of the app authorized to use the `protectedData` * * Default fetch for any app */ - authorizedApp?: AddressOrENS; + authorizedApp?: Address; /** - * Address or ENS of the user authorized to use the `protectedData` + * Address of the user authorized to use the `protectedData` * * Default fetch for any user */ - authorizedUser?: AddressOrENS; + authorizedUser?: Address; /** * Fetches the orderbook strictly specified for this user @@ -149,9 +148,9 @@ export type GetGrantedAccessParams = { }; export type GetProtectedDataParams = { - protectedDataAddress?: AddressOrENS; + protectedDataAddress?: Address; requiredSchema?: SearchableDataSchema; - owner?: AddressOrENS; + owner?: Address; createdAfterTimestamp?: number; page?: number; pageSize?: number; @@ -165,21 +164,21 @@ export type GrantAccessStatuses = export type GrantAccessParams = { /** - * Protected Data address or ENS + * Protected Data address */ - protectedData: AddressOrENS; + protectedData: Address; /** - * Address or ENS of the app authorized to use the `protectedData` + * Address of the app authorized to use the `protectedData` */ - authorizedApp: AddressOrENS; + authorizedApp: Address; /** - * Address or ENS of the user authorized to use the `protectedData` + * Address of the user authorized to use the `protectedData` * * The address zero `0x0000000000000000000000000000000000000000` can be use to authorize any user to use the `protectedData`. */ - authorizedUser: AddressOrENS; + authorizedUser: Address; /** * Price paid by the `authorizedUser` per access to the `protectedData` labeled in nRLC. @@ -266,23 +265,23 @@ export type RevokeAllAccessStatuses = export type RevokeAllAccessParams = { /** - * Protected Data address or ENS + * Protected Data address */ - protectedData: AddressOrENS; + protectedData: Address; /** - * Address or ENS of the app authorized to use the `protectedData` + * Address of the app authorized to use the `protectedData` * * Default revoke for any app */ - authorizedApp?: AddressOrENS; + authorizedApp?: Address; /** - * Address or ENS of the user authorized to use the `protectedData` + * Address of the user authorized to use the `protectedData` * * Default revoke for any user */ - authorizedUser?: AddressOrENS; + authorizedUser?: Address; /** * Callback function that will get called at each step of the process @@ -297,13 +296,13 @@ export type RevokedAccess = { // ---------------------TransferProtectedData Types------------------------------------ export type TransferParams = { - protectedData: AddressOrENS; - newOwner: AddressOrENS; + protectedData: Address; + newOwner: Address; }; export type TransferResponse = { address: Address; - to: AddressOrENS; + to: Address; txHash: string; }; @@ -321,14 +320,14 @@ export type ProcessProtectedDataStatuses = export type ProcessProtectedDataParams = { /** - * Address or ENS (Ethereum Name Service) of the protected data. + * Address of the protected data. */ - protectedData: AddressOrENS; + protectedData: Address; /** - * Address or ENS of the authorized application to process the protected data. + * Address of the authorized application to process the protected data. */ - app: AddressOrENS; + app: Address; /** * Address of an ERC734 whitelist contract authorized to access the protectedData, including the current user address. This address will be used to search for granted accesses instead of the user address. @@ -379,7 +378,7 @@ export type ProcessProtectedDataParams = { /** * The workerpool to use for the application's execution. (default iExec production workerpool) */ - workerpool?: AddressOrENS; + workerpool?: Address; /** * A boolean that indicates whether to use a voucher or no. @@ -389,7 +388,7 @@ export type ProcessProtectedDataParams = { /** * Override the voucher contract to use, must be combined with useVoucher: true the user must be authorized by the voucher's owner to use it. */ - voucherOwner?: AddressOrENS; + voucherOwner?: Address; /** * Enable result encryption for the processed data. @@ -449,9 +448,9 @@ export type PrepareBulkRequestParams = { bulkAccesses: GrantedAccess[]; /** - * Address or ENS of the app to use for processing the protected data + * Address of the app to use for processing the protected data */ - app: AddressOrENS; + app: Address; /** * Maximum number of protected data to process per task (any protected data exceeding this number will be processed in another task) @@ -489,7 +488,7 @@ export type PrepareBulkRequestParams = { /** * The workerpool to use for the application's execution. (default any workerpool) */ - workerpool?: AddressOrENS; + workerpool?: Address; /** * Enable result encryption for the processed data. @@ -561,7 +560,7 @@ export type ProcessBulkRequestParams = { /** * The workerpool to use for the application's execution. (default iExec production workerpool) */ - workerpool?: AddressOrENS; + workerpool?: Address; /** * A boolean that indicates whether to use a voucher or no. @@ -571,7 +570,7 @@ export type ProcessBulkRequestParams = { /** * Override the voucher contract to use, must be combined with useVoucher: true the user must be authorized by the voucher's owner to use it. */ - voucherOwner?: AddressOrENS; + voucherOwner?: Address; /** * Private key in PEM format for result decryption. diff --git a/packages/sdk/src/lib/types/graphQLTypes.ts b/packages/sdk/src/lib/types/graphQLTypes.ts index 664f04211..3f7de6e7e 100644 --- a/packages/sdk/src/lib/types/graphQLTypes.ts +++ b/packages/sdk/src/lib/types/graphQLTypes.ts @@ -1,4 +1,4 @@ -import { Address, AddressOrENS } from './commonTypes.js'; +import { Address } from './commonTypes.js'; /*************************************************************************** * Subgraph Types * @@ -9,7 +9,7 @@ import { Address, AddressOrENS } from './commonTypes.js'; export type OneProtectedData = { id: Address; name: string; - owner: { id: AddressOrENS }; + owner: { id: Address }; schema: Array>; creationTimestamp: number; multiaddr: string; // hex representation. Ex: "0xa50322122038d76d7059153e707cd0951cf2ff64d17f69352a285503800c7787c3af0c63dd" diff --git a/packages/sdk/src/lib/types/internalTypes.ts b/packages/sdk/src/lib/types/internalTypes.ts index dd249371e..3e6ef7dfd 100644 --- a/packages/sdk/src/lib/types/internalTypes.ts +++ b/packages/sdk/src/lib/types/internalTypes.ts @@ -1,13 +1,13 @@ import { GraphQLClient } from 'graphql-request'; -import { Address, BN, IExec } from 'iexec'; -import { AddressOrENS } from './commonTypes.js'; +import { BN, IExec } from 'iexec'; +import { Address } from './commonTypes.js'; export type IExecConsumer = { iexec: IExec; }; export type DataProtectorContractConsumer = { - dataprotectorContractAddress: AddressOrENS; + dataprotectorContractAddress: Address; }; export type ArweaveUploadConsumer = { diff --git a/packages/sdk/src/utils/resolveENS.ts b/packages/sdk/src/utils/resolveENS.ts deleted file mode 100644 index 7f4bcce63..000000000 --- a/packages/sdk/src/utils/resolveENS.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IExec } from 'iexec'; -import { ValidationError } from 'yup'; -import { isEnsTest } from './validators.js'; - -export const resolveENS = async ( - iexec: IExec, - address: string | undefined -): Promise => { - if (address && isEnsTest(address)) { - const resolved = await iexec.ens.resolveName(address); - if (!resolved) { - throw new ValidationError(`ENS name is not valid: ${address}`); - } - return resolved.toLowerCase(); - } - return address; -}; diff --git a/packages/sdk/src/utils/validators.ts b/packages/sdk/src/utils/validators.ts index db244cd00..a9e453ef8 100644 --- a/packages/sdk/src/utils/validators.ts +++ b/packages/sdk/src/utils/validators.ts @@ -18,8 +18,6 @@ export const throwIfMissing = (): never => { const isUndefined = (value: unknown) => value === undefined; const isAddressTest = (value: string) => isAddress(value); -export const isEnsTest = (value: string) => - value.endsWith('.eth') && value.length > 6; const isPositiveIntegerStringTest = (value: string) => /^\d+$/.test(value); const isZeroStringTest = (value: string) => value === '0'; @@ -48,15 +46,6 @@ export const addressSchema = () => (value) => isUndefined(value) || isAddressTest(value) ); -export const addressOrEnsSchema = () => - string() - .transform((value: string) => value?.toLowerCase() || value) - .test( - 'is-address-or-ens', - '${path} should be an ethereum address or a ENS name', - (value) => isUndefined(value) || isAddressTest(value) || isEnsTest(value) - ); - export const positiveIntegerStringSchema = () => string().test( 'is-positive-int', diff --git a/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts index 0c5b5f41c..dd966b214 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts @@ -1,7 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; import { HDNodeWallet, Wallet } from 'ethers'; import { IExecDataProtectorCore } from '../../../src/index.js'; -import { ValidationError } from '../../../src/utils/errors.js'; import { getTestConfig, timeouts } from '../../test-utils.js'; import { waitForSubgraphIndexing } from '../../utils/waitForSubgraphIndexing.js'; @@ -61,27 +60,6 @@ describe('dataProtectorCore.getProtectedData()', () => { timeouts.getProtectedData ); - it( - 'accept an optional owner (ENS)', - async () => { - const res = await dataProtectorCore.getProtectedData({ - owner: 'pierre.users.iexec.eth', - }); - expect(res).toBeDefined(); - }, - timeouts.getProtectedData - ); - - it('checks the owner ENS is valid', async () => { - await expect( - dataProtectorCore.getProtectedData({ - owner: 'this.ens.does.not.exist.eth', - }) - ).rejects.toThrow( - new ValidationError('ENS name is not valid: this.ens.does.not.exist.eth') - ); - }); - describe('When calling getProtectedData with a specific protectedDataAddress', () => { it( 'should return only this protectedData', diff --git a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts index 0b0438144..90b7bf437 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts @@ -21,7 +21,7 @@ describe('getGrantedAccess', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedData should be an ethereum address or a ENS name' + 'protectedData should be an ethereum address' ) ); }); @@ -42,7 +42,7 @@ describe('getGrantedAccess', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedApp should be an ethereum address or a ENS name' + 'authorizedApp should be an ethereum address' ) ); }); @@ -63,7 +63,7 @@ describe('getGrantedAccess', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedUser should be an ethereum address or a ENS name' + 'authorizedUser should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts index 13aa0581a..70060ac6f 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts @@ -14,8 +14,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, protectedDataAddress: invalidProtectedDataAddress, @@ -23,7 +21,7 @@ describe('dataProtectorCore > getProtectedData()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedDataAddress should be an ethereum address or a ENS name' + 'protectedDataAddress should be an ethereum address' ) ); }); @@ -39,8 +37,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, // @ts-expect-error This is intended to actually test yup runtime validation @@ -63,8 +59,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, owner: invalidOwnerAddress, @@ -72,7 +66,7 @@ describe('dataProtectorCore > getProtectedData()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'owner should be an ethereum address or a ENS name' + 'owner should be an ethereum address' ) ); }); @@ -86,8 +80,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, createdAfterTimestamp: invalidCreatedAfterTimestamp, @@ -109,8 +101,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, // @ts-expect-error This is intended to actually test yup runtime validation @@ -131,8 +121,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, page, @@ -152,8 +140,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, pageSize, @@ -173,8 +159,6 @@ describe('dataProtectorCore > getProtectedData()', () => { await expect( // --- WHEN getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error No need for graphQLClient here graphQLClient: {}, pageSize, @@ -203,8 +187,6 @@ describe('dataProtectorCore > getProtectedData()', () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error Minimal GraphQL client with only what's necessary for this test graphQLClient, protectedDataAddress, @@ -275,8 +257,6 @@ describe('dataProtectorCore > getProtectedData()', () => { // --- WHEN const protectedDataForOwner = await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error Minimal GraphQL client with only what's necessary for this test graphQLClient, owner: ownerAddress, @@ -337,8 +317,6 @@ describe('dataProtectorCore > getProtectedData()', () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, // @ts-expect-error Minimal GraphQL client with only what's necessary for this test graphQLClient, createdAfterTimestamp, @@ -382,8 +360,6 @@ describe('dataProtectorCore > getProtectedData()', () => { it('should correctly flatten the schema and include it in the subgraph query variables', async () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, graphQLClient, requiredSchema: { email: 'string', @@ -408,8 +384,6 @@ describe('dataProtectorCore > getProtectedData()', () => { it('should correctly flatten the schema and include it in the subgraph query variables', async () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, graphQLClient, requiredSchema: { photo: { @@ -444,8 +418,6 @@ describe('dataProtectorCore > getProtectedData()', () => { it('should correctly flatten the schema and include it in the subgraph query variables', async () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, graphQLClient, requiredSchema: { photo: ['image/jpeg', 'image/png'], @@ -481,8 +453,6 @@ describe('dataProtectorCore > getProtectedData()', () => { it('should correctly flatten the schema and include it in the subgraph query variables', async () => { // --- WHEN await getProtectedData({ - // @ts-expect-error No need for iexec here - iexec: {}, graphQLClient, requiredSchema: { photo: ['image/png'], diff --git a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts index ca4b7d306..65d5f0de9 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts @@ -54,7 +54,7 @@ describe('dataProtectorCore.grantAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedData should be an ethereum address or a ENS name' + 'protectedData should be an ethereum address' ) ); }); @@ -96,7 +96,7 @@ describe('dataProtectorCore.grantAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedApp should be an ethereum address or a ENS name' + 'authorizedApp should be an ethereum address' ) ); }); @@ -138,7 +138,7 @@ describe('dataProtectorCore.grantAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedUser should be an ethereum address or a ENS name' + 'authorizedUser should be an ethereum address' ) ); }); @@ -188,32 +188,6 @@ describe('dataProtectorCore.grantAccess()', () => { }); }); - describe('When given authorized app is NOT a valid ENS', () => { - it('should resolve it to its corresponding ethereum address', async () => { - // --- GIVEN - const invalidEns = 'not.a.valid.ens.eth'; - const iexec = { - ens: { - resolveName: jest - .fn<() => Promise>() - .mockResolvedValue(undefined), - }, - }; - - await expect( - // --- WHEN - grantAccess({ - // @ts-expect-error Minimal iexec implementation with only what's necessary for this test - iexec, - protectedData: getRandomAddress(), - authorizedApp: invalidEns, - }) - // --- THEN - ).rejects.toThrow( - new ValidationError('authorizedApp ENS name is not valid') - ); - }); - }); }); describe('When access has already been granted to this same app', () => { diff --git a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts index 05d7d64be..98d8fb173 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts @@ -156,7 +156,7 @@ describe('prepareBulkRequest', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError('app should be an ethereum address or a ENS name') + new ValidationError('app should be an ethereum address') ); }); }); @@ -308,7 +308,7 @@ describe('prepareBulkRequest', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'workerpool should be an ethereum address or a ENS name' + 'workerpool should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts index d8ce3439a..0bf6e399e 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts @@ -116,7 +116,7 @@ describe('processBulkRequest', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'workerpool should be an ethereum address or a ENS name' + 'workerpool should be an ethereum address' ) ); }); @@ -139,7 +139,7 @@ describe('processBulkRequest', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'voucherOwner should be an ethereum address or a ENS name' + 'voucherOwner should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts index eb1d7ad97..4afe0846a 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts @@ -98,7 +98,7 @@ describe('processProtectedData', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedData should be an ethereum address or a ENS name' + 'protectedData should be an ethereum address' ) ); }); @@ -142,7 +142,7 @@ describe('processProtectedData', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedApp should be an ethereum address or a ENS name' + 'authorizedApp should be an ethereum address' ) ); }); @@ -343,7 +343,7 @@ describe('processProtectedData', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'workerpool should be an ethereum address or a ENS name' + 'workerpool should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts index 6f81e88e9..05a68c48d 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts @@ -41,7 +41,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedData should be an ethereum address or a ENS name' + 'protectedData should be an ethereum address' ) ); }); @@ -63,7 +63,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedApp should be an ethereum address or a ENS name' + 'authorizedApp should be an ethereum address' ) ); }); @@ -86,7 +86,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'authorizedUser should be an ethereum address or a ENS name' + 'authorizedUser should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts b/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts index c3f94a2f5..fad098989 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts @@ -40,7 +40,7 @@ describe('dataProtectorCore.transferOwnership()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'protectedData should be an ethereum address or a ENS name' + 'protectedData should be an ethereum address' ) ); }); @@ -82,7 +82,7 @@ describe('dataProtectorCore.transferOwnership()', () => { // --- THEN ).rejects.toThrow( new ValidationError( - 'newOwner should be an ethereum address or a ENS name' + 'newOwner should be an ethereum address' ) ); }); diff --git a/packages/sdk/tests/unit/utils/validators.test.ts b/packages/sdk/tests/unit/utils/validators.test.ts index 9af6d7eef..987d49394 100644 --- a/packages/sdk/tests/unit/utils/validators.test.ts +++ b/packages/sdk/tests/unit/utils/validators.test.ts @@ -2,7 +2,6 @@ import { describe, it, expect } from '@jest/globals'; import { ValidationError } from '../../../src/utils/errors.js'; import { addressSchema, - addressOrEnsSchema, positiveIntegerStringSchema, positiveStrictIntegerStringSchema, grantedAccessSchema, @@ -60,65 +59,6 @@ describe('addressSchema()', () => { }); }); -describe('addressOrEnsSchema()', () => { - describe('validateSync()', () => { - const address = getRandomAddress(); - const EXPECTED_ERROR = new ValidationError( - 'this should be an ethereum address or a ENS name' - ); - - it('transforms to lowercase', () => { - const res = addressOrEnsSchema().validateSync(address); - expect(res).toBe(address.toLowerCase()); - }); - it('accepts undefined (is not required by default)', () => { - const res = addressOrEnsSchema().validateSync(undefined); - expect(res).toBeUndefined(); - }); - it('accepts case insensitive ethereum address', () => { - expect(addressOrEnsSchema().validateSync(address)).toBeDefined(); - expect( - addressOrEnsSchema().validateSync(address.toUpperCase()) - ).toBeDefined(); - expect( - addressOrEnsSchema().validateSync(address.toLowerCase()) - ).toBeDefined(); - }); - it('accepts string ending with ".eth"', () => { - expect(addressOrEnsSchema().validateSync('FOO.eth')).toBe('foo.eth'); - }); - it('does not accept null', () => { - expect(() => addressOrEnsSchema().validateSync(null)).toThrow( - CANNOT_BE_NULL_ERROR - ); - }); - it('does not accept empty string', () => { - expect(() => addressOrEnsSchema().validateSync('')).toThrow( - EXPECTED_ERROR - ); - }); - it('does not accept non address string', () => { - expect(() => addressOrEnsSchema().validateSync('test')).toThrow( - EXPECTED_ERROR - ); - }); - it('does not accept ENS name with label < 3 char', () => { - expect(() => addressOrEnsSchema().validateSync('ab.eth')).toThrow( - EXPECTED_ERROR - ); - }); - }); - describe('required()', () => { - describe('validateSync()', () => { - it('does not accept undefined', () => { - expect(() => - addressOrEnsSchema().required().validateSync(undefined) - ).toThrow(IS_REQUIRED_ERROR); - }); - }); - }); -}); - describe('positiveIntegerStringSchema()', () => { describe('validateSync()', () => { const EXPECTED_ERROR = new ValidationError( From 320ce6dd4f7d8a3918c0a3493dcf97eb34e193de Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:14:20 +0200 Subject: [PATCH 02/11] fix!: remove voucher support BREAKING CHANGE: Remove useVoucher and voucherOwner params from `processProtectedData` and `processBulkRequest`. --- .../dataProtectorCore/processBulkRequest.ts | 48 ++---------- .../dataProtectorCore/processProtectedData.ts | 49 ++---------- packages/sdk/src/lib/types/commonTypes.ts | 5 -- packages/sdk/src/lib/types/coreTypes.ts | 20 ----- packages/sdk/src/lib/types/internalTypes.ts | 15 +--- .../src/utils/processProtectedData.models.ts | 54 +------------ .../prepareBulkRequest.test.ts | 1 - .../processBulkRequest.test.ts | 76 ------------------- .../processProtectedData.test.ts | 1 - .../utils/mockAllForProcessProtectedData.ts | 4 +- 10 files changed, 14 insertions(+), 259 deletions(-) diff --git a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts index b3efef678..da8e8fff6 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts @@ -6,10 +6,7 @@ import { handleIfProtocolError, ValidationError, } from '../../utils/errors.js'; -import { - checkUserVoucher, - filterWorkerpoolOrders, -} from '../../utils/processProtectedData.models.js'; +import { filterWorkerpoolOrders } from '../../utils/processProtectedData.models.js'; import { addressSchema, booleanSchema, @@ -21,7 +18,6 @@ import { import { BulkRequest, DefaultWorkerpoolConsumer, - MatchOptions, OnStatusUpdateFn, ProcessBulkRequestParams, ProcessBulkRequestResponse, @@ -29,7 +25,7 @@ import { ProcessBulkRequestResponseWithResult, ProcessBulkRequestStatuses, } from '../types/index.js'; -import { IExecConsumer, VoucherInfo } from '../types/internalTypes.js'; +import { IExecConsumer } from '../types/internalTypes.js'; import { getResultFromCompletedTask } from './getResultFromCompletedTask.js'; import { waitForTaskCompletion } from './waitForTaskCompletion.js'; @@ -49,8 +45,6 @@ export const processBulkRequest = async < defaultWorkerpool, bulkRequest, workerpool, - useVoucher = false, - voucherOwner, path, pemPrivateKey, waitForResult = false, @@ -66,12 +60,6 @@ export const processBulkRequest = async < .default(defaultWorkerpool) // Default workerpool if none is specified .label('workerpool') .validateSync(workerpool); - const vUseVoucher = booleanSchema() - .label('useVoucher') - .validateSync(useVoucher); - const vVoucherOwner = addressSchema() - .label('voucherOwner') - .validateSync(voucherOwner); const vWaitForResult = booleanSchema() .label('waitForResult') .validateSync(waitForResult); @@ -101,23 +89,6 @@ export const processBulkRequest = async < } try { - let userVoucher: VoucherInfo | undefined; - if (vUseVoucher) { - try { - userVoucher = await iexec.voucher.showUserVoucher( - vVoucherOwner || vRequestorder.requester - ); - checkUserVoucher({ userVoucher }); - } catch (err) { - if (err?.message?.startsWith('No Voucher found for address')) { - throw new Error( - 'Oops, it seems your wallet is not associated with any voucher. Check on https://builder.iex.ec/' - ); - } - throw err; - } - } - vOnStatusUpdate({ title: 'FETCH_ORDERS', isDone: false, @@ -175,7 +146,7 @@ export const processBulkRequest = async < app: vRequestorder.app, dataset: vRequestorder.dataset, // For bulk requests, we don't specify a specific dataset requester: vRequestorder.requester, - isRequesterStrict: useVoucher, + isRequesterStrict: false, minTag: sumTags([apporder.tag, vRequestorder.tag]), category: 0, }) @@ -183,8 +154,6 @@ export const processBulkRequest = async < const desiredPriceWorkerpoolOrder = filterWorkerpoolOrders({ workerpoolOrders: workerpoolOrderbook.orders, workerpoolMaxPrice: Number(vRequestorder.workerpoolmaxprice), - useVoucher: vUseVoucher, - userVoucher, }); return desiredPriceWorkerpoolOrder; }); @@ -211,23 +180,16 @@ export const processBulkRequest = async < apporder: apporder, }; - const matchOptions: MatchOptions = { - useVoucher: vUseVoucher, - ...(vVoucherOwner ? { voucherAddress: userVoucher?.address } : {}), - }; - const { volume: matchableVolume, total, - sponsored, - } = await iexec.order.estimateMatchOrders(orders, matchOptions); + } = await iexec.order.estimateMatchOrders(orders); vOnStatusUpdate({ title: 'REQUEST_TO_PROCESS_BULK_DATA', isDone: false, payload: { cost: total.toString(), - sponsoredCost: vUseVoucher ? sponsored.toString() : undefined, remainingVolume, matchVolume: matchableVolume.toNumber(), totalVolume: volume, @@ -238,7 +200,7 @@ export const processBulkRequest = async < dealid, txHash, volume: matchedVolume, - } = await iexec.order.matchOrders(orders, matchOptions); + } = await iexec.order.matchOrders(orders); vOnStatusUpdate({ title: 'REQUEST_TO_PROCESS_BULK_DATA', diff --git a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts index dfbb00f19..6a1ae8159 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts @@ -11,10 +11,7 @@ import { handleIfProtocolError, ValidationError, } from '../../utils/errors.js'; -import { - checkUserVoucher, - filterWorkerpoolOrders, -} from '../../utils/processProtectedData.models.js'; +import { filterWorkerpoolOrders } from '../../utils/processProtectedData.models.js'; import { pushRequesterSecret } from '../../utils/pushRequesterSecret.js'; import { getPemFormattedKeyPair, @@ -33,13 +30,12 @@ import { import { isERC734 } from '../../utils/whitelist.js'; import { DefaultWorkerpoolConsumer, - MatchOptions, OnStatusUpdateFn, ProcessProtectedDataParams, ProcessProtectedDataResponse, ProcessProtectedDataStatuses, } from '../types/index.js'; -import { IExecConsumer, VoucherInfo } from '../types/internalTypes.js'; +import { IExecConsumer } from '../types/internalTypes.js'; import { getResultFromCompletedTask } from './getResultFromCompletedTask.js'; import { getWhitelistContract } from './smartContract/getWhitelistContract.js'; import { isAddressInWhitelist } from './smartContract/whitelistContract.read.js'; @@ -63,8 +59,6 @@ export const processProtectedData = async < inputFiles, secrets, workerpool, - useVoucher = false, - voucherOwner, encryptResult = false, pemPrivateKey, waitForResult = true, @@ -102,12 +96,6 @@ export const processProtectedData = async < .default(defaultWorkerpool) // Default workerpool if none is specified .label('workerpool') .validateSync(workerpool); - const vUseVoucher = booleanSchema() - .label('useVoucher') - .validateSync(useVoucher); - const vVoucherOwner = addressSchema() - .label('voucherOwner') - .validateSync(voucherOwner); const vEncryptResult = booleanSchema() .label('encryptResult') .validateSync(encryptResult); @@ -156,23 +144,6 @@ export const processProtectedData = async < requester = vUserWhitelist; } } - let userVoucher: VoucherInfo | undefined; - if (vUseVoucher) { - try { - userVoucher = await iexec.voucher.showUserVoucher( - vVoucherOwner || requester - ); - checkUserVoucher({ userVoucher }); - } catch (err) { - if (err?.message?.startsWith('No Voucher found for address')) { - throw new Error( - 'Oops, it seems your wallet is not associated with any voucher. Check on https://builder.iex.ec/' - ); - } - throw err; - } - } - vOnStatusUpdate({ title: 'FETCH_ORDERS', isDone: false, @@ -233,7 +204,7 @@ export const processProtectedData = async < app: vApp, dataset: vProtectedData, requester: requester, // public orders + user specific orders - isRequesterStrict: useVoucher, // If voucher, we only want user specific orders + isRequesterStrict: false, minTag: workerpoolMinTag, category: 0, }), @@ -244,7 +215,7 @@ export const processProtectedData = async < app: vUserWhitelist, dataset: vProtectedData, requester: requester, // public orders + user specific orders - isRequesterStrict: useVoucher, // If voucher, we only want user specific orders + isRequesterStrict: false, minTag: workerpoolMinTag, category: 0, }), @@ -256,8 +227,6 @@ export const processProtectedData = async < ...workerpoolOrderbookForAppWhitelist.orders, ], workerpoolMaxPrice: vWorkerpoolMaxPrice, - useVoucher: vUseVoucher, - userVoucher, }); if (!desiredPriceWorkerpoolOrder) { throw new Error( @@ -367,15 +336,7 @@ export const processProtectedData = async < apporder: apporder, datasetorder: datasetorder, }; - const matchOptions: MatchOptions = { - useVoucher: vUseVoucher, - ...(vVoucherOwner ? { voucherAddress: userVoucher?.address } : {}), - }; - - const { dealid: dealId, txHash } = await iexec.order.matchOrders( - orders, - matchOptions - ); + const { dealid: dealId, txHash } = await iexec.order.matchOrders(orders); const taskId = await iexec.deal.computeTaskId(dealId, 0); vOnStatusUpdate({ diff --git a/packages/sdk/src/lib/types/commonTypes.ts b/packages/sdk/src/lib/types/commonTypes.ts index 1f2993330..08aadeff1 100644 --- a/packages/sdk/src/lib/types/commonTypes.ts +++ b/packages/sdk/src/lib/types/commonTypes.ts @@ -106,11 +106,6 @@ export interface SearchableDataSchema | SearchableSchemaEntryType[] > {} -export type MatchOptions = { - useVoucher: boolean; - voucherAddress?: string; -}; - export type DefaultWorkerpoolConsumer = { defaultWorkerpool: Address; }; diff --git a/packages/sdk/src/lib/types/coreTypes.ts b/packages/sdk/src/lib/types/coreTypes.ts index 539d2e772..0b92b1d71 100644 --- a/packages/sdk/src/lib/types/coreTypes.ts +++ b/packages/sdk/src/lib/types/coreTypes.ts @@ -380,16 +380,6 @@ export type ProcessProtectedDataParams = { */ workerpool?: Address; - /** - * A boolean that indicates whether to use a voucher or no. - */ - useVoucher?: boolean; - - /** - * Override the voucher contract to use, must be combined with useVoucher: true the user must be authorized by the voucher's owner to use it. - */ - voucherOwner?: Address; - /** * Enable result encryption for the processed data. * @default false @@ -562,16 +552,6 @@ export type ProcessBulkRequestParams = { */ workerpool?: Address; - /** - * A boolean that indicates whether to use a voucher or no. - */ - useVoucher?: boolean; - - /** - * Override the voucher contract to use, must be combined with useVoucher: true the user must be authorized by the voucher's owner to use it. - */ - voucherOwner?: Address; - /** * Private key in PEM format for result decryption. * diff --git a/packages/sdk/src/lib/types/internalTypes.ts b/packages/sdk/src/lib/types/internalTypes.ts index 3e6ef7dfd..1f1d8cc53 100644 --- a/packages/sdk/src/lib/types/internalTypes.ts +++ b/packages/sdk/src/lib/types/internalTypes.ts @@ -1,5 +1,5 @@ import { GraphQLClient } from 'graphql-request'; -import { BN, IExec } from 'iexec'; +import { IExec } from 'iexec'; import { Address } from './commonTypes.js'; export type IExecConsumer = { @@ -21,16 +21,3 @@ export type SubgraphConsumer = { export type PocoSubgraphConsumer = { pocoSubgraphClient: GraphQLClient; }; - -export type VoucherInfo = { - owner: Address; - address: Address; - type: BN; - balance: BN; - expirationTimestamp: BN; - sponsoredApps: Address[]; - sponsoredDatasets: Address[]; - sponsoredWorkerpools: Address[]; - allowanceAmount: BN; - authorizedAccounts: Address[]; -}; diff --git a/packages/sdk/src/utils/processProtectedData.models.ts b/packages/sdk/src/utils/processProtectedData.models.ts index b51b25120..318d8e0d1 100644 --- a/packages/sdk/src/utils/processProtectedData.models.ts +++ b/packages/sdk/src/utils/processProtectedData.models.ts @@ -1,74 +1,24 @@ -import { BN } from 'iexec'; import { PublishedWorkerpoolorder } from 'iexec/IExecOrderbookModule'; -import { VoucherInfo } from '../lib/types/internalTypes.js'; - -function bnToNumber(bn: BN) { - return Number(bn.toString()); -} - -export function checkUserVoucher({ - userVoucher, -}: { - userVoucher: VoucherInfo; -}) { - if (bnToNumber(userVoucher.expirationTimestamp) < Date.now() / 1000) { - throw new Error( - 'Oops, it seems your voucher has expired. You might want to ask for a top up. Check on https://builder.iex.ec/' - ); - } - - if (bnToNumber(userVoucher.balance) === 0) { - throw new Error( - 'Oops, it seems your voucher is empty. You might want to ask for a top up. Check on https://builder.iex.ec/' - ); - } -} export function filterWorkerpoolOrders({ workerpoolOrders, workerpoolMaxPrice, - useVoucher, - userVoucher, }: { workerpoolOrders: PublishedWorkerpoolorder[]; workerpoolMaxPrice: number; - useVoucher: boolean; - userVoucher?: VoucherInfo; }) { if (workerpoolOrders.length === 0) { return null; } - let eligibleWorkerpoolOrders = workerpoolOrders; - let maxVoucherSponsoredAmount = 0; // may be safer to use bigint - - if (useVoucher) { - if (!userVoucher) { - throw new Error( - 'useVoucher === true but userVoucher is undefined? Hum...' - ); - } - // only voucher sponsored workerpoolorders - eligibleWorkerpoolOrders = eligibleWorkerpoolOrders.filter(({ order }) => - userVoucher.sponsoredWorkerpools.includes(order.workerpool) - ); - if (eligibleWorkerpoolOrders.length === 0) { - throw new Error( - 'Found some workerpool orders but none can be sponsored by your voucher.' - ); - } - maxVoucherSponsoredAmount = bnToNumber(userVoucher.balance); - } - - const [cheapestOrder] = eligibleWorkerpoolOrders.sort( + const [cheapestOrder] = workerpoolOrders.sort( (order1, order2) => order1.order.workerpoolprice - order2.order.workerpoolprice ); if ( !cheapestOrder || - cheapestOrder.order.workerpoolprice > - workerpoolMaxPrice + maxVoucherSponsoredAmount + cheapestOrder.order.workerpoolprice > workerpoolMaxPrice ) { return null; } diff --git a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts index 98d8fb173..364d7a030 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts @@ -64,7 +64,6 @@ jest.unstable_mockModule( filterWorkerpoolOrders: jest.fn( () => mockWorkerpoolOrderbook.orders[0].order ), - checkUserVoucher: jest.fn(), }) ); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts index 0bf6e399e..f9e7fa7e3 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts @@ -10,8 +10,6 @@ import { getRequiredFieldMessage, mockWorkerpoolOrderbook, } from '../../test-utils.js'; -import { resolveWithOneAppOrder } from '../../utils/appOrders.js'; -import { resolveWithOneWorkerpoolOrder } from '../../utils/workerpoolOrders.js'; // Mock bulk request for testing const mockBulkRequest = { @@ -58,7 +56,6 @@ jest.unstable_mockModule( filterWorkerpoolOrders: jest.fn( () => mockWorkerpoolOrderbook.orders[0].order ), - checkUserVoucher: jest.fn(), }) ); @@ -122,28 +119,6 @@ describe('processBulkRequest', () => { }); }); - describe('When given voucherOwner is NOT valid', () => { - it('should throw a yup ValidationError with the correct message', async () => { - // --- GIVEN - const invalidVoucherOwner = '0x123456...'; - - await expect( - // --- WHEN - processBulkRequest({ - // @ts-expect-error No need for iexec here - iexec: {}, - defaultWorkerpool: getRandomAddress(), - bulkRequest: mockBulkRequest, - voucherOwner: invalidVoucherOwner, - }) - // --- THEN - ).rejects.toThrow( - new ValidationError( - 'voucherOwner should be an ethereum address' - ) - ); - }); - }); }); describe('When there is NO app orders', () => { @@ -192,55 +167,4 @@ describe('processBulkRequest', () => { }); }); - describe('When voucher is used but user has no voucher', () => { - it('should throw a WorkflowError with the correct message', async () => { - // --- GIVEN - const iexec = { - wallet: { - getAddress: jest - .fn<() => Promise>() - .mockResolvedValue(getRandomAddress()), - }, - voucher: { - showUserVoucher: jest - .fn<() => Promise>() - .mockRejectedValue( - new Error('No Voucher found for address test-address') - ), - }, - orderbook: { - fetchAppOrderbook: resolveWithOneAppOrder(), - fetchWorkerpoolOrderbook: resolveWithOneWorkerpoolOrder(), - }, - order: { - prepareDatasetBulk: jest - .fn<() => Promise<{ cid: string; volume: number }>>() - .mockResolvedValue({ cid: 'test-cid', volume: 1 }), - createRequestorder: jest - .fn<() => Promise>() - .mockResolvedValue({}), - signRequestorder: jest.fn<() => Promise>().mockResolvedValue({}), - }, - }; - - await expect( - // --- WHEN - processBulkRequest({ - // @ts-expect-error Minimal iexec implementation with only what's necessary for this test - iexec, - bulkRequest: mockBulkRequest, - defaultWorkerpool: getRandomAddress(), - useVoucher: true, - }) - // --- THEN - ).rejects.toThrow( - new WorkflowError({ - message: processProtectedDataErrorMessage, - errorCause: Error( - 'Oops, it seems your wallet is not associated with any voucher. Check on https://builder.iex.ec/' - ), - }) - ); - }); - }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts index 4afe0846a..f812ce1e4 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts @@ -43,7 +43,6 @@ jest.unstable_mockModule( filterWorkerpoolOrders: jest.fn( () => mockWorkerpoolOrderbook.orders[0].order ), - checkUserVoucher: jest.fn(), }) ); diff --git a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts index 3537f2802..b020c3dc9 100644 --- a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts +++ b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts @@ -1,5 +1,5 @@ import { jest } from '@jest/globals'; -import BN from 'bn.js'; // TODO use utils.BN from iexec and remove bn.js deps when https://github.com/iExecBlockchainComputing/iexec-sdk/pull/354 is released +import { BN } from 'iexec/utils'; import { Address, Dealid } from 'iexec'; import { getRandomAddress, @@ -41,12 +41,10 @@ export function mockAllForProcessProtectedData({ .fn< () => Promise<{ total: BN; - sponsored: BN; }> >() .mockResolvedValue({ total: new BN(0), - sponsored: new BN(0), }), matchOrders: jest .fn< From c7c11af7c7717259c2af454d53c06bd59132eac2 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:33:44 +0200 Subject: [PATCH 03/11] test: update test infrastructure to run on arbitrum-sepolia fork --- packages/sdk/package.json | 3 +- .../dataProtectorCore/processBulkRequest.ts | 6 +- packages/sdk/tests/docker-compose.yml | 472 ++++++++---------- packages/sdk/tests/e2e/constructor.test.ts | 17 - .../getGrantedAccess.test.ts | 138 ++--- .../getProtectedData.test.ts | 12 +- .../e2e/dataProtectorCore/grantAccess.test.ts | 41 +- .../inspectBulkRequest.test.ts | 12 +- .../processProtectedData.test.ts | 12 +- .../e2e/dataProtectorCore/protectData.test.ts | 16 +- .../dataProtectorCore/revokeAllAccess.test.ts | 21 +- .../dataProtectorCore/revokeOneAccess.test.ts | 15 +- .../transferOwnership.test.ts | 5 +- .../waitForTaskCompletion.test.ts | 23 +- packages/sdk/tests/prepare-iexec.js | 31 -- packages/sdk/tests/prepare-test-env.js | 86 ++-- packages/sdk/tests/test-utils.ts | 107 ++-- .../getGrantedAccess.test.ts | 12 +- .../getProtectedData.test.ts | 4 +- .../dataProtectorCore/grantAccess.test.ts | 13 +- .../prepareBulkRequest.test.ts | 4 +- .../processBulkRequest.test.ts | 6 +- .../processProtectedData.test.ts | 12 +- .../dataProtectorCore/revokeAllAccess.test.ts | 12 +- .../transferOwnership.test.ts | 8 +- packages/sdk/tests/utils/appOrders.ts | 8 +- packages/sdk/tests/utils/datasetOrders.ts | 10 +- packages/sdk/tests/utils/workerpoolOrders.ts | 2 +- 28 files changed, 505 insertions(+), 603 deletions(-) delete mode 100644 packages/sdk/tests/e2e/constructor.test.ts delete mode 100644 packages/sdk/tests/prepare-iexec.js diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 41f0632ba..489c0f88d 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -17,7 +17,6 @@ "build": "rimraf dist && tsc --project tsconfig.build.json", "build:watch": "npm run build -- --watch", "check-types": "tsc --noEmit", - "test:prepare": "node tests/prepare-iexec.js", "test": "NODE_OPTIONS=--experimental-vm-modules jest --testMatch \"**/tests/**/*.test.ts\"", "test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest --testMatch \"**/tests/**/*.test.ts\" --coverage", "test:unit": "NODE_OPTIONS=--experimental-vm-modules jest --testMatch \"**/tests/unit/**/*.test.ts\"", @@ -33,7 +32,7 @@ "generate:abi": "rimraf generated/abis && node tools/generateAbiModules.mjs", "refresh-abis": "mkdir -p .tmp && cp -r abis/core/registry .tmp/ 2>/dev/null || true && rm -rf abis && mkdir -p abis/core && cp -r ../smart-contract/abis/. ./abis/core/ && if [ -d .tmp/registry ]; then mkdir -p abis/core/registry && cp -r .tmp/registry/. ./abis/core/registry/ && rm -rf .tmp; fi", "stop-test-stack": "cd tests && docker compose --project-name dataprotector-sdk down --volumes --remove-orphans", - "start-test-stack": "cd tests && npm run stop-test-stack && node prepare-test-env.js && docker compose --project-name dataprotector-sdk build && docker compose --project-name dataprotector-sdk up -d && npm run test:prepare" + "start-test-stack": "cd tests && npm run stop-test-stack && node prepare-test-env.js && docker compose --project-name dataprotector-sdk build && docker compose --project-name dataprotector-sdk up -d" }, "repository": { "type": "git", diff --git a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts index da8e8fff6..4d002b703 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processBulkRequest.ts @@ -180,10 +180,8 @@ export const processBulkRequest = async < apporder: apporder, }; - const { - volume: matchableVolume, - total, - } = await iexec.order.estimateMatchOrders(orders); + const { volume: matchableVolume, total } = + await iexec.order.estimateMatchOrders(orders); vOnStatusUpdate({ title: 'REQUEST_TO_PROCESS_BULK_DATA', diff --git a/packages/sdk/tests/docker-compose.yml b/packages/sdk/tests/docker-compose.yml index c959f66a8..7c84e1caf 100644 --- a/packages/sdk/tests/docker-compose.yml +++ b/packages/sdk/tests/docker-compose.yml @@ -1,251 +1,221 @@ -services: - bellecour-fork: - restart: 'no' - image: ghcr.io/foundry-rs/foundry:v1.0.0 - entrypoint: anvil - command: '--host 0.0.0.0 --port 8545 --block-time 1 --hardfork berlin --fork-url $BELLECOUR_FORK_URL --fork-block-number $BELLECOUR_FORK_BLOCK --chain-id 134 --gas-limit 6700000 --gas-price 0' - expose: - - 8545 - ports: - - 8545:8545 - healthcheck: - # check port 8545 is open without nc - test: (echo >/dev/tcp/$(hostname)/8545) &>/dev/null - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s - - sms: - image: iexechub/iexec-sms:8.7.0 - restart: unless-stopped - environment: - JAVA_TOOL_OPTIONS: '-Xmx256M' - IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS: http://bellecour-fork:8545 - IEXEC_HUB_ADDRESS: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f' - IEXEC_SMS_TEE_RUNTIME_FRAMEWORK: scone - IEXEC_SMS_IMAGE_LAS_IMAGE: 'las-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_IMAGE: 'pre-compute-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_FINGERPRINT: 'pre-compute-fingerprint' - IEXEC_TEE_WORKER_POST_COMPUTE_IMAGE: 'post-compute-image' - IEXEC_TEE_WORKER_POST_COMPUTE_FINGERPRINT: 'post-compute-fingerprint' - ports: - - 13300:13300 - healthcheck: - test: curl -f localhost:13300/actuator/health || exit 1 - depends_on: - bellecour-fork: - condition: service_healthy - - result-proxy: - image: iexechub/iexec-result-proxy:7.1.0 - restart: unless-stopped - environment: - IEXEC_PRIVATE_CHAIN_ADDRESS: http://bellecour-fork:8545 - IEXEC_PUBLIC_CHAIN_ADDRESS: http://bellecour-fork:8545 - IEXEC_HUB_ADDRESS: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f' - MONGO_HOST: result-proxy-mongo - MONGO_PORT: 13202 - IEXEC_IPFS_HOST: ipfs - ports: - - 13200:13200 - depends_on: - bellecour-fork: - condition: service_healthy - result-proxy-mongo: - condition: service_started - ipfs: - condition: service_started - - result-proxy-mongo: - restart: unless-stopped - image: library/mongo:4.2 - entrypoint: '/bin/bash' - command: -c "mongod --bind_ip_all --port 13202" - expose: - - 13202 - - ipfs: - restart: unless-stopped - image: ipfs/go-ipfs:v0.9.1 - expose: - - 8080 - - 5001 - ports: - - 8080:8080 - - 5001:5001 - - market-mongo: - image: mongo:7.0.6 - restart: unless-stopped - expose: - - 27017 - ports: - - 27017:27017 - - market-redis: - image: redis:7.0.7-alpine - restart: unless-stopped - command: redis-server --appendonly yes - expose: - - 6379 - ports: - - 6379:6379 - - market-watcher: - image: iexechub/iexec-market-watcher:6.4 - restart: unless-stopped - environment: - CHAIN: BELLECOUR - START_BLOCK: $BELLECOUR_FORK_BLOCK - ETH_WS_HOST: ws://bellecour-fork:8545 - ETH_RPC_HOST: http://bellecour-fork:8545 - MONGO_HOST: market-mongo - REDIS_HOST: market-redis - depends_on: - bellecour-fork: - condition: service_healthy - market-redis: - condition: service_started - market-mongo: - condition: service_started - - market-api: - image: iexechub/iexec-market-api:7.1.0 - restart: unless-stopped - ports: - - 3000:3000 - expose: - - 3000 - environment: - CHAINS: BELLECOUR_FORK - BELLECOUR_FORK_ETH_RPC_HOST: http://bellecour-fork:8545 - BELLECOUR_FORK_CHAIN_ID: 134 - BELLECOUR_FORK_IS_NATIVE: 'true' - BELLECOUR_FORK_IEXEC_ADDRESS: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f' - MONGO_HOST: market-mongo - REDIS_HOST: market-redis - RATE_LIMIT_MAX: 10000 - RATE_LIMIT_PERIOD: 60000 - MAX_OPEN_ORDERS_PER_WALLET: 1000 - depends_on: - bellecour-fork: - condition: service_healthy - market-redis: - condition: service_started - market-mongo: - condition: service_started - - graphnode-postgres: - image: postgres:12 - restart: unless-stopped - command: - - 'postgres' - - '-cshared_preload_libraries=pg_stat_statements' - expose: - - 5432 - environment: - POSTGRES_USER: graphnode - POSTGRES_PASSWORD: password - POSTGRES_DB: graphnode-db - PGDATA: '/var/lib/postgresql/data' - POSTGRES_INITDB_ARGS: '-E UTF8 --locale=C' - healthcheck: - test: pg_isready -U graphnode -d graphnode-db - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s - - graphnode: - image: graphprotocol/graph-node:v0.34.1 - restart: unless-stopped - expose: - - 8000 - - 8020 - ports: - # GraphQL HTTP - - 8000:8000 - # GraphQL WS - # - 8001:8001 - # admin RPC - - 8020:8020 - # # metrics - - 8040:8040 - environment: - postgres_host: graphnode-postgres - postgres_port: 5432 - postgres_user: graphnode - postgres_pass: password - postgres_db: graphnode-db - ipfs: ipfs:5001 - ethereum: bellecour:http://bellecour-fork:8545 - GRAPH_ETHEREUM_GENESIS_BLOCK_NUMBER: $BELLECOUR_FORK_BLOCK - depends_on: - bellecour-fork: - condition: service_healthy - graphnode-postgres: - condition: service_healthy - ipfs: - condition: service_started - healthcheck: - test: netcat -w 1 0.0.0.0 8020 - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - - dataprotector-subgraph-deployer: - image: dataprotector-subgraph-deployer - restart: 'on-failure' - build: - context: ../../.. - dockerfile: packages/subgraph/deployer.Dockerfile - depends_on: - graphnode: - condition: service_healthy - ipfs: - condition: service_started - environment: - START_BLOCK: $BELLECOUR_FORK_BLOCK - NETWORK_NAME: bellecour - GRAPHNODE_URL: http://graphnode:8020 - IPFS_URL: http://ipfs:5001 - ENV: prod - - poco-subgraph-deployer: - image: iexechub/poco-subgraph-deployer:v2.1.2 - restart: 'on-failure' - depends_on: - graphnode: - condition: service_healthy - ipfs: - condition: service_started - environment: - START_BLOCK: $BELLECOUR_FORK_BLOCK - NETWORK_NAME: bellecour - GRAPHNODE_URL: http://graphnode:8020 - IPFS_URL: http://ipfs:5001 - ENV: prod - - stack-ready: - image: bash - command: - - echo "all services ready" - depends_on: - bellecour-fork: - condition: service_healthy - graphnode: - condition: service_healthy - sms: - condition: service_healthy - market-watcher: - condition: service_started - market-api: - condition: service_started - result-proxy: - condition: service_started - dataprotector-subgraph-deployer: - condition: service_completed_successfully - poco-subgraph-deployer: - condition: service_completed_successfully +services: + arbitrum-sepolia-fork: + restart: 'no' + image: ghcr.io/foundry-rs/foundry:v1.0.0 + entrypoint: anvil + command: '--host 0.0.0.0 --port 8545 --block-time 1 --fork-url $ARBITRUM_SEPOLIA_FORK_URL --fork-block-number $ARBITRUM_SEPOLIA_FORK_BLOCK --chain-id 421614' + expose: + - 8545 + ports: + - 8545:8545 + healthcheck: + # check port 8545 is open without nc + test: (echo >/dev/tcp/$(hostname)/8545) &>/dev/null + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + + sms: + image: iexechub/iexec-sms:8.7.0 + restart: unless-stopped + environment: + JAVA_TOOL_OPTIONS: '-Xmx256M' + IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS: http://arbitrum-sepolia-fork:8545 + IEXEC_HUB_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + IEXEC_SMS_TEE_RUNTIME_FRAMEWORK: scone + IEXEC_SMS_IMAGE_LAS_IMAGE: 'las-image' + IEXEC_TEE_WORKER_PRE_COMPUTE_IMAGE: 'pre-compute-image' + IEXEC_TEE_WORKER_PRE_COMPUTE_FINGERPRINT: 'pre-compute-fingerprint' + IEXEC_TEE_WORKER_POST_COMPUTE_IMAGE: 'post-compute-image' + IEXEC_TEE_WORKER_POST_COMPUTE_FINGERPRINT: 'post-compute-fingerprint' + ports: + - 13300:13300 + healthcheck: + test: curl -f localhost:13300/actuator/health || exit 1 + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + ipfs: + restart: unless-stopped + image: ipfs/go-ipfs:v0.9.1 + expose: + - 8080 + - 5001 + ports: + - 8080:8080 + - 5001:5001 + + market-mongo: + image: mongo:7.0.6 + restart: unless-stopped + expose: + - 27017 + ports: + - 27017:27017 + + market-redis: + image: redis:7.0.7-alpine + restart: unless-stopped + command: redis-server --appendonly yes + expose: + - 6379 + ports: + - 6379:6379 + + market-watcher: + image: iexechub/iexec-market-watcher:6.4 + restart: unless-stopped + environment: + CHAIN: ARBITRUM_SEPOLIA + START_BLOCK: $ARBITRUM_SEPOLIA_FORK_BLOCK + CHAIN_ID: 421614 + IEXEC_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + ETH_WS_HOST: ws://arbitrum-sepolia-fork:8545 + ETH_RPC_HOST: http://arbitrum-sepolia-fork:8545 + MONGO_HOST: market-mongo + REDIS_HOST: market-redis + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + market-redis: + condition: service_started + market-mongo: + condition: service_started + + market-api: + image: iexechub/iexec-market-api:7.1.0 + restart: unless-stopped + ports: + - 3000:3000 + expose: + - 3000 + environment: + CHAINS: ARBITRUM_SEPOLIA_FORK + ARBITRUM_SEPOLIA_FORK_ETH_RPC_HOST: http://arbitrum-sepolia-fork:8545 + ARBITRUM_SEPOLIA_FORK_CHAIN_ID: 421614 + ARBITRUM_SEPOLIA_FORK_IEXEC_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + MONGO_HOST: market-mongo + REDIS_HOST: market-redis + RATE_LIMIT_MAX: 10000 + RATE_LIMIT_PERIOD: 60000 + MAX_OPEN_ORDERS_PER_WALLET: 1000 + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + market-redis: + condition: service_started + market-mongo: + condition: service_started + + graphnode-postgres: + image: postgres:12 + restart: unless-stopped + command: + - 'postgres' + - '-cshared_preload_libraries=pg_stat_statements' + expose: + - 5432 + environment: + POSTGRES_USER: graphnode + POSTGRES_PASSWORD: password + POSTGRES_DB: graphnode-db + PGDATA: '/var/lib/postgresql/data' + POSTGRES_INITDB_ARGS: '-E UTF8 --locale=C' + healthcheck: + test: pg_isready -U graphnode -d graphnode-db + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + + graphnode: + image: graphprotocol/graph-node:v0.43.0 + restart: unless-stopped + expose: + - 8000 + - 8020 + ports: + # GraphQL HTTP + - 8000:8000 + # GraphQL WS + # - 8001:8001 + # admin RPC + - 8020:8020 + # # metrics + - 8040:8040 + environment: + postgres_host: graphnode-postgres + postgres_port: 5432 + postgres_user: graphnode + postgres_pass: password + postgres_db: graphnode-db + ipfs: ipfs:5001 + ethereum: arbitrum-sepolia:http://arbitrum-sepolia-fork:8545 + GRAPH_ETHEREUM_GENESIS_BLOCK_NUMBER: $ARBITRUM_SEPOLIA_INDEX_BLOCK + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + graphnode-postgres: + condition: service_healthy + ipfs: + condition: service_started + healthcheck: + test: netcat -w 1 0.0.0.0 8020 + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + + dataprotector-subgraph-deployer: + image: dataprotector-subgraph-deployer + restart: 'on-failure' + build: + context: ../../.. + dockerfile: packages/subgraph/deployer.Dockerfile + depends_on: + graphnode: + condition: service_healthy + ipfs: + condition: service_started + environment: + START_BLOCK: $ARBITRUM_SEPOLIA_INDEX_BLOCK + NETWORK_NAME: arbitrum-sepolia + GRAPHNODE_URL: http://graphnode:8020 + IPFS_URL: http://ipfs:5001 + ENV: prod + + poco-subgraph-deployer: + image: iexechub/poco-subgraph-deployer:v2.1.2 + restart: 'on-failure' + depends_on: + graphnode: + condition: service_healthy + ipfs: + condition: service_started + environment: + START_BLOCK: $ARBITRUM_SEPOLIA_INDEX_BLOCK + NETWORK_NAME: arbitrum-sepolia + GRAPHNODE_URL: http://graphnode:8020 + IPFS_URL: http://ipfs:5001 + ENV: prod + + stack-ready: + image: bash + command: + - echo "all services ready" + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + graphnode: + condition: service_healthy + sms: + condition: service_healthy + market-watcher: + condition: service_started + market-api: + condition: service_started + dataprotector-subgraph-deployer: + condition: service_completed_successfully + poco-subgraph-deployer: + condition: service_completed_successfully diff --git a/packages/sdk/tests/e2e/constructor.test.ts b/packages/sdk/tests/e2e/constructor.test.ts deleted file mode 100644 index e930c62b4..000000000 --- a/packages/sdk/tests/e2e/constructor.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import { IExecDataProtector } from '../../src/index.js'; -import { getTestConfig } from '../test-utils.js'; - -describe('When instantiating SDK without a signer', () => { - describe('When calling a read method', () => { - it('should work as expected', async () => { - // --- GIVEN - const dataProtector = new IExecDataProtector(...getTestConfig()); - - // --- WHEN/THEN - await expect( - dataProtector.core.getProtectedData() - ).resolves.not.toThrow(); - }); - }); -}); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/getGrantedAccess.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/getGrantedAccess.test.ts index 0049e4a00..dccb57065 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/getGrantedAccess.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/getGrantedAccess.test.ts @@ -3,7 +3,11 @@ import { HDNodeWallet, Wallet } from 'ethers'; import { IExec } from 'iexec'; import { MarketCallError } from 'iexec/errors'; import { TEE_TAG } from '../../../src/config/config.js'; -import { IExecDataProtectorCore, WorkflowError } from '../../../src/index.js'; +import { + IExecDataProtectorCore, + ProtectedDataWithSecretProps, + WorkflowError, +} from '../../../src/index.js'; import { pushRequesterSecret } from '../../../src/utils/pushRequesterSecret.js'; import { MAX_EXPECTED_BLOCKTIME, @@ -34,8 +38,8 @@ async function consumeProtectedDataOrder( const appOrderbook = await iexec.orderbook.fetchAppOrderbook({ app: app, - minTag: ['tee', 'scone'], - maxTag: ['tee', 'scone'], + minTag: ['tee', 'tdx'], + maxTag: ['tee', 'tdx'], workerpool: workerpool, }); const appOrder = appOrderbook.orders[0]?.order; @@ -48,8 +52,8 @@ async function consumeProtectedDataOrder( app: app, dataset: protectedData, requester: await iexec.wallet.getAddress(), - minTag: ['tee', 'scone'], - maxTag: ['tee', 'scone'], + minTag: ['tee', 'tdx'], + maxTag: ['tee', 'tdx'], category: 0, }); const workerpoolOrder = workerpoolOrderbook.orders[0]?.order; @@ -93,9 +97,8 @@ describe('dataProtectorCore.getGrantedAccess()', () => { beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); }); it( @@ -165,29 +168,31 @@ describe('dataProtectorCore.getGrantedAccess()', () => { 'should correctly create a protectedData, grant access, and fetch access for protected data', async () => { const userWalletAddress = Wallet.createRandom().address; - const [protectedData, sconeAppAddress] = await Promise.all([ + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey + ); + const [protectedData, teeAppAddress] = await Promise.all([ dataProtectorCore.protectData({ data: { doNotUse: 'test' }, }), deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + ethProvider: appDeployerProvider, }), ]); const grantedAccess = await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userWalletAddress, }); const { grantedAccess: fetchedContacts } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userWalletAddress, }); const result = fetchedContacts.filter( (contact) => - contact.apprestrict.toLowerCase() === sconeAppAddress.toLowerCase() && + contact.apprestrict.toLowerCase() === teeAppAddress.toLowerCase() && contact.requesterrestrict.toLowerCase() === userWalletAddress.toLowerCase() ); @@ -198,38 +203,40 @@ describe('dataProtectorCore.getGrantedAccess()', () => { describe('pagination', () => { async function grantAccessToRandomUsers( - protectedData, - sconeAppAddress, - count + protectedData: ProtectedDataWithSecretProps, + teeAppAddress: string, + count: number ) { for (let i = 0; i < count; i++) { const userWalletAddress = Wallet.createRandom().address; await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userWalletAddress, }); } } const grantedAccessCount = 42; - let protectedData; - let sconeAppAddress; + let protectedData: ProtectedDataWithSecretProps; + let teeAppAddress: string; beforeAll(async () => { - [protectedData, sconeAppAddress] = await Promise.all([ + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey + ); + [protectedData, teeAppAddress] = await Promise.all([ dataProtectorCore.protectData({ data: { doNotUse: 'pagination test' }, }), deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + ethProvider: appDeployerProvider, }), ]); await grantAccessToRandomUsers( protectedData, - sconeAppAddress, + teeAppAddress, grantedAccessCount ); }, (grantedAccessCount + 2) * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME); @@ -239,7 +246,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); expect(grantedAccessResponse.count).toBe(grantedAccessCount); expect(grantedAccessResponse.grantedAccess.length).toBe(20); @@ -252,7 +259,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, page: 1, }); expect(grantedAccessResponse.grantedAccess.length).toBeLessThanOrEqual( @@ -267,7 +274,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, page: 2, }); expect(grantedAccessResponse.grantedAccess.length).toBeLessThanOrEqual( @@ -282,7 +289,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, pageSize: 13, }); expect(grantedAccessResponse.grantedAccess.length).toBe(13); @@ -295,7 +302,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, page: 0, pageSize: 15, }); @@ -309,7 +316,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { async () => { const grantedAccessResponse = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, page: 100, pageSize: 20, }); @@ -321,14 +328,13 @@ describe('dataProtectorCore.getGrantedAccess()', () => { describe('remainingAccess', () => { let iexec: IExec; - let sconeAppAddress: string; + let teeAppAddress: string; let workerpoolAddress: string; beforeAll(async () => { - const [ethProvider, options] = getTestConfig(wallet.privateKey); - sconeAppAddress = await deployRandomApp({ + const [ethProvider, options] = await getTestConfig(wallet.privateKey); + teeAppAddress = await deployRandomApp({ ethProvider, - teeFramework: 'scone', }); iexec = new IExec({ ethProvider }, options.iexecOptions); @@ -336,9 +342,9 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // create and publish app order await iexec.order .createApporder({ - app: sconeAppAddress, + app: teeAppAddress, volume: 1000, - tag: ['tee', 'scone'], + tag: ['tee', 'tdx'], }) .then(iexec.order.signApporder) .then(iexec.order.publishApporder); @@ -355,7 +361,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { workerpool: workerpoolAddress, category: 0, volume: 1000, - tag: ['tee', 'scone'], + tag: ['tee', 'tdx'], }) .then(iexec.order.signWorkerpoolorder) .then(iexec.order.publishWorkerpoolorder); @@ -376,7 +382,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // grant access with volume = 5 const accessBefore = await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, numberOfAccess: 5, }); @@ -387,7 +393,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { await consumeProtectedDataOrder( iexec, protectedData.address, - sconeAppAddress, + teeAppAddress, workerpoolAddress, { 1: 'requester secret 1', @@ -400,7 +406,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfter } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -424,7 +430,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // grant access with volume = 2 await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, numberOfAccess: 2, }); @@ -433,7 +439,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: initialAccess } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -444,7 +450,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { await consumeProtectedDataOrder( iexec, protectedData.address, - sconeAppAddress, + teeAppAddress, workerpoolAddress, { 1: 'requester secret 1', @@ -456,7 +462,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterFirst } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -467,7 +473,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { await consumeProtectedDataOrder( iexec, protectedData.address, - sconeAppAddress, + teeAppAddress, workerpoolAddress, { 1: 'requester secret 1', @@ -479,7 +485,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterSecond } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -504,7 +510,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // grant access with volume = 2 const accessBeforeRevoke = await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, numberOfAccess: 2, }); @@ -513,7 +519,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: initialAccess } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -527,7 +533,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterRevoke } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -551,7 +557,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // grant access with volume = 2 await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, numberOfAccess: 2, }); @@ -565,7 +571,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterRevoke } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -593,7 +599,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // Grant access with volume = 5 await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, numberOfAccess: 5, }); @@ -602,7 +608,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { await consumeProtectedDataOrder( iexec, protectedData.address, - sconeAppAddress, + teeAppAddress, workerpoolAddress, { 1: 'Subject 1', 2: 'Content 1' }, 'args1' @@ -610,7 +616,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { await consumeProtectedDataOrder( iexec, protectedData.address, - sconeAppAddress, + teeAppAddress, workerpoolAddress, { 1: 'Subject 2', 2: 'Content 2' }, 'args2' @@ -620,7 +626,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterConsumption } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -634,7 +640,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { const { grantedAccess: accessAfterRevoke } = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: userAddress, }); @@ -649,7 +655,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { 'Throws error when the marketplace is unavailable', async () => { const unavailableDataProtector = new IExecDataProtectorCore( - getTestWeb3SignerProvider(wallet.privateKey), + await getTestWeb3SignerProvider(wallet.privateKey), { iexecOptions: { iexecGatewayURL: 'https://unavailable.market.url', @@ -686,10 +692,12 @@ describe('dataProtectorCore.getGrantedAccess()', () => { name: 'test protected data for bulk filtering', }); - // Deploy a SCONE app - const sconeAppAddress = await deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + // Deploy a TEE app + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey + ); + const teeAppAddress = await deployRandomApp({ + ethProvider: appDeployerProvider, }); const regularUserAddress = Wallet.createRandom().address; @@ -698,7 +706,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // Grant regular access (non-bulk) await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: regularUserAddress, numberOfAccess: 5, allowBulk: false, @@ -707,7 +715,7 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // Grant bulk access await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: bulkUserAddress, allowBulk: true, }); @@ -715,14 +723,14 @@ describe('dataProtectorCore.getGrantedAccess()', () => { // Test without bulkOnly filter - should return both orders const allAccess = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); expect(allAccess.grantedAccess.length).toBe(2); // Test with bulkOnly filter - should return only bulk orders const bulkOnlyAccess = await dataProtectorCore.getGrantedAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, bulkOnly: true, }); expect(bulkOnlyAccess.grantedAccess.length).toBe(1); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts index dd966b214..83526fe47 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/getProtectedData.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it } from '@jest/globals'; +import { beforeAll, beforeEach, describe, expect, it } from '@jest/globals'; import { HDNodeWallet, Wallet } from 'ethers'; import { IExecDataProtectorCore } from '../../../src/index.js'; import { getTestConfig, timeouts } from '../../test-utils.js'; @@ -10,9 +10,8 @@ describe('dataProtectorCore.getProtectedData()', () => { beforeEach(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); }); it( @@ -455,9 +454,8 @@ describe('dataProtectorCore.getProtectedData()', () => { describe('When calling getProtectedData with a specific requiredSchema', () => { const ownerWallet = Wallet.createRandom(); beforeAll(async () => { - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(ownerWallet.privateKey) - ); + const config = await getTestConfig(ownerWallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); await dataProtectorCore.protectData({ name: 'bool', data: { secret: { value: true } }, diff --git a/packages/sdk/tests/e2e/dataProtectorCore/grantAccess.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/grantAccess.test.ts index 79f3ea4dc..fb881f96a 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/grantAccess.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/grantAccess.test.ts @@ -30,27 +30,26 @@ describe('dataProtectorCore.grantAccess()', () => { let dataProtectorCore: IExecDataProtectorCore; let wallet: HDNodeWallet; let protectedData: ProtectedDataWithSecretProps; - let sconeAppAddress: string; - const VALID_WHITELIST_CONTRACT = '0x680f6C2A2a6ce97ea632a7408b0E673396dd5581'; + let teeAppAddress: string; + const VALID_WHITELIST_CONTRACT = '0x09d59e1b696d0cb69f46bf762412636e8652ab58'; const INVALID_WHITELIST_CONTRACT = '0xF2f72A635b41cDBFE5784A2C6Bdd349536967579'; beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey ); - const results = await Promise.all([ + [protectedData, teeAppAddress] = await Promise.all([ dataProtectorCore.protectData({ data: { doNotUse: 'test' }, }), deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + ethProvider: appDeployerProvider, }), ]); - protectedData = results[0]; - sconeAppAddress = results[1]; }, 6 * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME); let input: any; @@ -68,7 +67,7 @@ describe('dataProtectorCore.grantAccess()', () => { const onStatusUpdateMock = jest.fn(); const grantedAccess = await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, onStatusUpdate: onStatusUpdateMock, }); expect(grantedAccess).toBeDefined(); @@ -100,12 +99,12 @@ describe('dataProtectorCore.grantAccess()', () => { await dataProtectorCore.grantAccess({ ...input, authorizedUser: ethers.ZeroAddress, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); // grantAccess to specific user const grantedAccess = await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); expect(grantedAccess.requesterrestrict).toEqual( @@ -121,19 +120,19 @@ describe('dataProtectorCore.grantAccess()', () => { // grantAccess to specific user await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); // grantAccess a second time await expect( dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }) ).rejects.toThrow( new WorkflowError({ message: grantAccessErrorMessage, errorCause: Error( - `An access has been already granted to the user: ${input.authorizedUser.toLowerCase()} with the app: ${sconeAppAddress.toLowerCase()}` + `An access has been already granted to the user: ${input.authorizedUser.toLowerCase()} with the app: ${teeAppAddress.toLowerCase()}` ), }) ); @@ -142,11 +141,11 @@ describe('dataProtectorCore.grantAccess()', () => { ); it( - 'sets the TEE tag with a Scone app', + 'always sets the TEE tag', async () => { const grantedAccess = await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, }); expect(grantedAccess.tag).toBe( '0x0000000000000000000000000000000000000000000000000000000000000001' @@ -208,7 +207,7 @@ describe('dataProtectorCore.grantAccess()', () => { 'Throws error when the marketplace is unavailable', async () => { const unavailableDataProtector = new IExecDataProtectorCore( - getTestWeb3SignerProvider(wallet.privateKey), + await getTestWeb3SignerProvider(wallet.privateKey), { iexecOptions: { iexecGatewayURL: 'https://unavailable.market.url', @@ -220,7 +219,7 @@ describe('dataProtectorCore.grantAccess()', () => { const onStatusUpdateMock = jest.fn(); await unavailableDataProtector.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, onStatusUpdate: onStatusUpdateMock, }); } catch (e) { @@ -247,7 +246,7 @@ describe('dataProtectorCore.grantAccess()', () => { const onStatusUpdateMock = jest.fn(); const grantedAccess = await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, allowBulk: true, pricePerAccess: 0, onStatusUpdate: onStatusUpdateMock, @@ -281,7 +280,7 @@ describe('dataProtectorCore.grantAccess()', () => { const onStatusUpdateMock = jest.fn(); const grantedAccess = await dataProtectorCore.grantAccess({ ...input, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, allowBulk: false, onStatusUpdate: onStatusUpdateMock, }); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/inspectBulkRequest.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/inspectBulkRequest.test.ts index 064eb481e..28d56eae7 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/inspectBulkRequest.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/inspectBulkRequest.test.ts @@ -25,18 +25,16 @@ describe('dataProtectorCore.inspectBulkRequest()', () => { beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); // create app & workerpool - const [ethProvider, options] = getTestConfig(wallet.privateKey); + const [ethProvider, options] = await getTestConfig(wallet.privateKey); appAddress = await deployRandomApp({ ethProvider, - teeFramework: 'scone', }); iexec = new IExec({ ethProvider }, options.iexecOptions); await iexec.order - .createApporder({ app: appAddress, volume: 1000, tag: ['tee', 'scone'] }) + .createApporder({ app: appAddress, volume: 1000, tag: ['tee', 'tdx'] }) .then(iexec.order.signApporder) .then(iexec.order.publishApporder); const { address: workerpool } = await iexec.workerpool.deployWorkerpool({ @@ -49,7 +47,7 @@ describe('dataProtectorCore.inspectBulkRequest()', () => { workerpool: workerpoolAddress, category: 0, volume: 1000, - tag: ['tee', 'scone'], + tag: ['tee', 'tdx'], }) .then(iexec.order.signWorkerpoolorder) .then(iexec.order.publishWorkerpoolorder); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/processProtectedData.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/processProtectedData.test.ts index 6ba2f71ba..53efd632c 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/processProtectedData.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/processProtectedData.test.ts @@ -22,18 +22,16 @@ describe('dataProtectorCore.processProtectedData() (waitForResult: false)', () = beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); // create app & workerpool - const [ethProvider, options] = getTestConfig(wallet.privateKey); + const [ethProvider, options] = await getTestConfig(wallet.privateKey); appAddress = await deployRandomApp({ ethProvider, - teeFramework: 'scone', }); iexec = new IExec({ ethProvider }, options.iexecOptions); await iexec.order - .createApporder({ app: appAddress, volume: 1000, tag: ['tee', 'scone'] }) + .createApporder({ app: appAddress, volume: 1000, tag: ['tee', 'tdx'] }) .then(iexec.order.signApporder) .then(iexec.order.publishApporder); const { address: workerpool } = await iexec.workerpool.deployWorkerpool({ @@ -46,7 +44,7 @@ describe('dataProtectorCore.processProtectedData() (waitForResult: false)', () = workerpool: workerpoolAddress, category: 0, volume: 1000, - tag: ['tee', 'scone'], + tag: ['tee', 'tdx'], }) .then(iexec.order.signWorkerpoolorder) .then(iexec.order.publishWorkerpoolorder); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/protectData.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/protectData.test.ts index 5b33c98bd..590e85b53 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/protectData.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/protectData.test.ts @@ -1,6 +1,13 @@ import fsPromises from 'fs/promises'; import path from 'path'; -import { beforeEach, describe, expect, it } from '@jest/globals'; +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + it, +} from '@jest/globals'; import { HDNodeWallet, Wallet } from 'ethers'; import { IExec } from 'iexec'; import { SmsCallError } from 'iexec/errors'; @@ -24,9 +31,8 @@ describe('dataProtectorCore.protectData()', () => { let wallet: HDNodeWallet; beforeEach(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); }); it( @@ -112,7 +118,7 @@ describe('dataProtectorCore.protectData()', () => { 'should throw error when sms is not available', async () => { const unavailableDataProtector = new IExecDataProtectorCore( - getTestWeb3SignerProvider(wallet.privateKey), + await getTestWeb3SignerProvider(wallet.privateKey), { iexecOptions: { ...getTestIExecOption(), diff --git a/packages/sdk/tests/e2e/dataProtectorCore/revokeAllAccess.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/revokeAllAccess.test.ts index e695b0492..8e8580dd6 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/revokeAllAccess.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/revokeAllAccess.test.ts @@ -24,9 +24,12 @@ import { sleep } from '../../utils/waitForSubgraphIndexing.js'; describe('dataProtectorCore.revokeAllAccess()', () => { const wallet = Wallet.createRandom(); - const dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + let dataProtectorCore: IExecDataProtectorCore; + + beforeAll(async () => { + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); + }); it( 'pass with a valid input', @@ -42,20 +45,22 @@ describe('dataProtectorCore.revokeAllAccess()', () => { describe('when an access is granted', () => { // same value used for the whole suite to save some execution time let protectedData: ProtectedDataWithSecretProps; - let sconeAppAddress: string; + let teeAppAddress: string; beforeAll(async () => { + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey + ); const result = await Promise.all([ dataProtectorCore.protectData({ data: { doNotUse: 'test' }, }), deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + ethProvider: appDeployerProvider, }), ]); protectedData = result[0]; - sconeAppAddress = result[1]; + teeAppAddress = result[1]; }, 4 * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME); let authorizedUser: Address; @@ -64,7 +69,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { authorizedUser = getRandomAddress(); await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser, }); }, MAX_EXPECTED_WEB2_SERVICES_TIME); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/revokeOneAccess.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/revokeOneAccess.test.ts index 30b658e9b..4416b530a 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/revokeOneAccess.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/revokeOneAccess.test.ts @@ -14,24 +14,25 @@ describe('dataProtectorCore.revokeOneAccess()', () => { let dataProtectorCore: IExecDataProtectorCore; let wallet: HDNodeWallet; let protectedData: ProtectedDataWithSecretProps; - let sconeAppAddress: string; + let teeAppAddress: string; beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); + const [appDeployerProvider] = await getTestConfig( + Wallet.createRandom().privateKey ); const result = await Promise.all([ dataProtectorCore.protectData({ data: { doNotUse: 'test' }, }), deployRandomApp({ - ethProvider: getTestConfig(Wallet.createRandom().privateKey)[0], - teeFramework: 'scone', + ethProvider: appDeployerProvider, }), ]); protectedData = result[0]; - sconeAppAddress = result[1]; + teeAppAddress = result[1]; }, 4 * MAX_EXPECTED_BLOCKTIME + MAX_EXPECTED_WEB2_SERVICES_TIME); it( @@ -39,7 +40,7 @@ describe('dataProtectorCore.revokeOneAccess()', () => { async () => { const grantedAccess = await dataProtectorCore.grantAccess({ protectedData: protectedData.address, - authorizedApp: sconeAppAddress, + authorizedApp: teeAppAddress, authorizedUser: getRandomAddress(), }); const res = await dataProtectorCore.revokeOneAccess(grantedAccess); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/transferOwnership.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/transferOwnership.test.ts index 0f1b58467..6ccaa00d5 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/transferOwnership.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/transferOwnership.test.ts @@ -15,9 +15,8 @@ describe('dataProtectorCore.transferOwnership()', () => { beforeAll(async () => { wallet = Wallet.createRandom(); - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(wallet.privateKey) - ); + const config = await getTestConfig(wallet.privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); protectedData = await dataProtectorCore.protectData({ data: { doNotUse: 'test' }, }); diff --git a/packages/sdk/tests/e2e/dataProtectorCore/waitForTaskCompletion.test.ts b/packages/sdk/tests/e2e/dataProtectorCore/waitForTaskCompletion.test.ts index 0407aded8..748b5e490 100644 --- a/packages/sdk/tests/e2e/dataProtectorCore/waitForTaskCompletion.test.ts +++ b/packages/sdk/tests/e2e/dataProtectorCore/waitForTaskCompletion.test.ts @@ -7,18 +7,17 @@ describe('dataProtectorCore.waitForTaskCompletion()', () => { let dataProtectorCore: IExecDataProtectorCore; beforeAll(async () => { - dataProtectorCore = new IExecDataProtectorCore( - ...getTestConfig(Wallet.createRandom().privateKey) - ); + const config = await getTestConfig(Wallet.createRandom().privateKey); + dataProtectorCore = new IExecDataProtectorCore(...config); }); it('should return when the task is completed', async () => { - // https://explorer.iex.ec/bellecour/task/0xb4655f62bdb841a3b54363b113c4204bf4fee76ab9029f33dc1218ab495970d7 + // https://explorer.iex.ec/arbitrum-sepolia-testnet/task/0x52c74460f422beb2b247cb3fd9ba6ae48b75cb5b17b3212dc2ad8a121116a2fa const onStatusUpdate = jest.fn(); const COMPLETED_TASKID = - '0xb4655f62bdb841a3b54363b113c4204bf4fee76ab9029f33dc1218ab495970d7'; + '0x52c74460f422beb2b247cb3fd9ba6ae48b75cb5b17b3212dc2ad8a121116a2fa'; const COMPLETED_DEALID = - '0xb5091be0385c80545cdd12e7c678b96dbb6338cf699324f8f2aa94d3f33f6eda'; + '0x2c97513bbef02a71b4cf555466f1dcc65e42720cc7d938f8eb53d93cf5ecaccd'; const res = await dataProtectorCore.waitForTaskCompletion({ dealId: COMPLETED_DEALID, taskId: COMPLETED_TASKID, @@ -36,11 +35,11 @@ describe('dataProtectorCore.waitForTaskCompletion()', () => { }); it('should return when the task is failed', async () => { - // https://explorer.iex.ec/bellecour/task/0x000b16d5517e44ca70744ec156e8374ae525c9ab902169fe01d909370e5778e0 + // https://explorer.iex.ec/arbitrum-sepolia-testnet/task/0x929cf32f0a1298170a54edfd1ffbd0a21cb2dbe5d96dbeb935583073ac61ec8f const FAILED_TASKID = - '0x000b16d5517e44ca70744ec156e8374ae525c9ab902169fe01d909370e5778e0'; + '0x929cf32f0a1298170a54edfd1ffbd0a21cb2dbe5d96dbeb935583073ac61ec8f'; const FAILED_DEALID = - '0xd613b7c6c4a022efe129fd93ce547eba71fc1055e0b42d20b11ad1f3505ad0a5'; + '0xd5b0b2af7c40e0e879f27d51c4b134e115fb9eb103f253603649fae09abd25c4'; const onStatusUpdate = jest.fn(); const res = await dataProtectorCore.waitForTaskCompletion({ dealId: FAILED_DEALID, @@ -59,11 +58,11 @@ describe('dataProtectorCore.waitForTaskCompletion()', () => { }); it('should return when the task is in timeout', async () => { - // https://explorer.iex.ec/bellecour/task/0x012b3d2f21ea3c8c0cc2a40ce06df028df84d1b53b7dae98d5352e79427b93a6 + // https://explorer.iex.ec/arbitrum-sepolia-testnet/task/0xeda9b137c56d31b02b17b097e464fd3982c46c3939745463e4abe73edf1ae8f8 const TIMEOUT_TASKID = - '0x012b3d2f21ea3c8c0cc2a40ce06df028df84d1b53b7dae98d5352e79427b93a6'; + '0x81c2ce94e358879ef165902d22ba18bc6f79964395a4eb2892d4895a66e4ffd1'; const TIMEOUT_DEALID = - '0xab15a51de7a3829fca1d3666b81b53e9e9ced0aa71bf20e7ebee1be1bdb3ee33'; + '0x12388731f990da5d6a63a579bbf2d822930532881c16750737cab7cd4574cdde'; const onStatusUpdate = jest.fn(); const res = await dataProtectorCore.waitForTaskCompletion({ dealId: TIMEOUT_DEALID, diff --git a/packages/sdk/tests/prepare-iexec.js b/packages/sdk/tests/prepare-iexec.js deleted file mode 100644 index f181eac09..000000000 --- a/packages/sdk/tests/prepare-iexec.js +++ /dev/null @@ -1,31 +0,0 @@ -import { readFile, writeFile } from 'fs/promises'; -import { resolve } from 'path'; - -const disableCheckImplementedOnChain = async () => { - const configModulePath = resolve( - 'node_modules/iexec/dist/esm/common/utils/config.js' - ); - - const configModule = await readFile(configModulePath, 'utf8'); - - const OG_CODE_SNIPPET = - 'export const checkImplementedOnChain = (chainId, featureName) => {'; - - const REPLACEMENT_CODE_SNIPPET = - 'export const checkImplementedOnChain = (chainId, featureName) => { return;'; - - if (!configModule.includes(REPLACEMENT_CODE_SNIPPET)) { - console.log('disabling checkImplementedOnChain implementation...'); - const patchedConfigModule = configModule.replace( - OG_CODE_SNIPPET, - REPLACEMENT_CODE_SNIPPET - ); - - await writeFile(configModulePath, patchedConfigModule, 'utf8'); - } -}; - -disableCheckImplementedOnChain().catch((e) => { - console.error(`Failed to disable checkImplementedOnChain: ${e}`); - process.exit(1); -}); diff --git a/packages/sdk/tests/prepare-test-env.js b/packages/sdk/tests/prepare-test-env.js index 7cdb445ba..59676a0ad 100644 --- a/packages/sdk/tests/prepare-test-env.js +++ b/packages/sdk/tests/prepare-test-env.js @@ -1,33 +1,53 @@ -import { writeFileSync } from 'fs'; - -const forkUrl = 'https://bellecour.iex.ec'; - -fetch(forkUrl, { - method: 'POST', - body: JSON.stringify({ - jsonrpc: 2.0, - method: 'eth_blockNumber', - params: [], - id: 1, - }), -}) - .then((res) => res.json()) - .then((jsonRes) => { - const forkBlockNumber = parseInt(jsonRes.result.substring(2), 16); - - console.log('Creating .env file for docker-compose test-stack'); - writeFileSync( - '.env', - `############ THIS FILE IS GENERATED ############ -# run "node prepare-test-env.js" to regenerate # -################################################ - -# blockchain node to use as the reference for the local fork -BELLECOUR_FORK_URL=${forkUrl} -# block number to fork from -BELLECOUR_FORK_BLOCK=${forkBlockNumber}` - ); - }) - .catch((e) => { - throw Error(`Failed to get current block number from ${forkUrl}: ${e}`); - }); +import { writeFileSync } from 'fs'; + +const arbitrumSepoliaForkUrl = + process.env.ARBITRUM_SEPOLIA_FORK_URL || + 'https://sepolia-rollup.arbitrum.io/rpc'; + +const arbitrumSepoliaForkBlock = await getCurrentBlockNumber( + arbitrumSepoliaForkUrl +); + +console.log('Creating .env file for docker-compose test-stack'); +writeFileSync( + '.env', + `############ THIS FILE IS GENERATED ############ +# run "node prepare-test-env.js" to regenerate # +################################################ + +# blockchain node to use as the reference for the local fork +ARBITRUM_SEPOLIA_FORK_URL=${arbitrumSepoliaForkUrl} +# block number to fork from +ARBITRUM_SEPOLIA_FORK_BLOCK=${arbitrumSepoliaForkBlock} +# block number to index from (should be fork block + 1 to skip all existing ArbitrumInternalTxType which is not supported by a graphnode connected to anvil) +ARBITRUM_SEPOLIA_INDEX_BLOCK=${arbitrumSepoliaForkBlock + 1}` +); + +async function getCurrentBlockNumber(forkUrl) { + const blockNumber = await fetch(forkUrl, { + method: 'POST', + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_blockNumber', + params: [], + id: 1, + }), + headers: { + 'Content-Type': 'application/json', + }, + }) + .then((res) => res.json()) + .then((jsonRes) => { + console.log( + `Current block number of ${forkUrl} is ${JSON.stringify(jsonRes)}` + ); + const forkBlockNumber = parseInt(jsonRes.result.substring(2), 16); + return forkBlockNumber; + }) + .catch((e) => { + throw new Error( + `Failed to get current block number from ${forkUrl}: ${e}` + ); + }); + return blockNumber; +} diff --git a/packages/sdk/tests/test-utils.ts b/packages/sdk/tests/test-utils.ts index e675e576e..b0cf81745 100644 --- a/packages/sdk/tests/test-utils.ts +++ b/packages/sdk/tests/test-utils.ts @@ -1,49 +1,73 @@ import { jest } from '@jest/globals'; import { Wallet, JsonRpcProvider, ethers } from 'ethers'; -import { IExecAppModule, IExecConfig, TeeFramework, utils } from 'iexec'; +import { IExecAppModule, IExecConfig, utils } from 'iexec'; import { type DataProtectorConfigOptions, type Web3SignerProvider, } from '../src/index.js'; -import { getWeb3Provider } from '../src/utils/getWeb3Provider.js'; import { WAIT_FOR_SUBGRAPH_INDEXING } from './utils/waitForSubgraphIndexing.js'; const TEST_CHAIN = { rpcURL: 'http://localhost:8545', - chainId: '134', + chainId: '421614', smsURL: 'http://127.0.0.1:13300', - resultProxyURL: 'http://127.0.0.1:13200', // TODO remove iexecGatewayURL: 'http://127.0.0.1:3000', - pocoSubgraphURL: 'http://127.0.0.1:8000/subgraphs/name/bellecour/poco-v5', + pocoSubgraphURL: + 'http://127.0.0.1:8000/subgraphs/name/arbitrum-sepolia/poco-v5', provider: new JsonRpcProvider('http://localhost:8545'), }; -export const getTestWeb3SignerProvider = ( +export const setBalance = async ( + address: string, + targetWeiBalance: ethers.BigNumberish +) => { + await fetch(TEST_CHAIN.rpcURL, { + method: 'POST', + body: JSON.stringify({ + method: 'anvil_setBalance', + params: [address, ethers.toBeHex(targetWeiBalance)], + id: 1, + jsonrpc: '2.0', + }), + headers: { + 'Content-Type': 'application/json', + }, + }); +}; + +export const getTestWeb3SignerProvider = async ( privateKey: string = Wallet.createRandom().privateKey -): Web3SignerProvider => - utils.getSignerFromPrivateKey(TEST_CHAIN.rpcURL, privateKey); +): Promise => { + const { address } = new Wallet(privateKey); + await setBalance(address, 10n ** 18n); // prefund the account with 1 ETH to be able to do transactions in tests + return utils.getSignerFromPrivateKey(TEST_CHAIN.rpcURL, privateKey); +}; export const getTestRpcProvider = () => new JsonRpcProvider(TEST_CHAIN.rpcURL); export const getTestIExecOption = () => ({ smsURL: TEST_CHAIN.smsURL, - resultProxyURL: TEST_CHAIN.resultProxyURL, iexecGatewayURL: TEST_CHAIN.iexecGatewayURL, pocoSubgraphURL: TEST_CHAIN.pocoSubgraphURL, }); -export const getTestConfig = ( - privateKey?: string -): [Web3SignerProvider, DataProtectorConfigOptions] => { - const ethProvider = privateKey - ? getTestWeb3SignerProvider(privateKey) - : undefined; +export const getTestConfig = async ( + privateKey?: T +): Promise< + [ + T extends string ? Web3SignerProvider : undefined, + DataProtectorConfigOptions + ] +> => { + const ethProvider = ( + privateKey ? await getTestWeb3SignerProvider(privateKey) : undefined + ) as T extends string ? Web3SignerProvider : undefined; const options = { iexecOptions: getTestIExecOption(), ipfsGateway: 'http://127.0.0.1:8080', ipfsNode: 'http://127.0.0.1:5001', subgraphUrl: - 'http://127.0.0.1:8000/subgraphs/name/bellecour/dataprotector-v2', + 'http://127.0.0.1:8000/subgraphs/name/arbitrum-sepolia/dataprotector-v2', }; return [ethProvider, options]; }; @@ -65,14 +89,10 @@ export const getRandomTxHash = () => { return hash; }; -export const deployRandomApp = async ( - options: { - ethProvider?: Web3SignerProvider; - teeFramework?: TeeFramework; - } = {} -) => { - const ethProvider = - options.ethProvider || getWeb3Provider(Wallet.createRandom().privateKey); +export const deployRandomApp = async (params: { + ethProvider: Web3SignerProvider; +}) => { + const ethProvider = params.ethProvider; const iexecAppModule = new IExecAppModule({ ethProvider }); const { address } = await iexecAppModule.deployApp({ owner: ethProvider.address, @@ -81,24 +101,11 @@ export const deployRandomApp = async ( multiaddr: 'foo/bar:baz', checksum: '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', - mrenclave: - options.teeFramework && - ({ - // base - framework: options.teeFramework, - version: 'v0', - fingerprint: 'thumb', - // scone specific - entrypoint: options.teeFramework === 'scone' ? 'foo' : undefined, - heapSize: options.teeFramework === 'scone' ? 1 : undefined, - } as any), }); return address; }; /** - * on bellecour the blocktime is expected to be 5sec but in case of issue on the network this blocktime can reach unexpected length - * * use this variable as a reference blocktime for tests timeout * * when the network is degraded, tweak the `MAX_EXPECTED_BLOCKTIME` value to reflect the network conditions @@ -194,7 +201,7 @@ export const mockWorkerpoolOrderbook = { }, orderHash: '0x4dacfe7ed8883f9d3034d3367c7e6d8f5bc2f9434a58b2a60d480948e216f6d8', - chainId: 134, + chainId: 421614, publicationTimestamp: '2025-02-25T15:10:16.612Z', signer: '0x0c2e2F5c360cB58dC9A4813fA29656b56b546BF3', status: 'open', @@ -220,7 +227,7 @@ export const mockAppOrderbook = { }, orderHash: '0x64208bc3580bbee092c4a4efb26629cf885a2f1e99b6b4d9bd809ea85b58332f', - chainId: 134, + chainId: 421614, publicationTimestamp: '2025-02-05T14:35:51.271Z', signer: '0x9cfFa14604A6836E9d6fBAcCc624cfE0bE3Be5B4', status: 'open', @@ -240,24 +247,6 @@ export function observableMockComplete() { return jest.fn<() => Promise>().mockResolvedValue(mockObservable); } -export const setBalance = async ( - address: string, - targetWeiBalance: ethers.BigNumberish -) => { - await fetch(TEST_CHAIN.rpcURL, { - method: 'POST', - body: JSON.stringify({ - method: 'anvil_setBalance', - params: [address, ethers.toBeHex(targetWeiBalance)], - id: 1, - jsonrpc: '2.0', - }), - headers: { - 'Content-Type': 'application/json', - }, - }); -}; - export const setNRlcBalance = async ( address: string, nRlcTargetBalance: ethers.BigNumberish @@ -272,7 +261,7 @@ export const depositNRlcForAccount = async ( ) => { const sponsorWallet = Wallet.createRandom(); await setNRlcBalance(sponsorWallet.address, nRlcAmount); - const ethProvider = getTestConfig(sponsorWallet.privateKey)[0]; + const [ethProvider] = await getTestConfig(sponsorWallet.privateKey); const iexecConfig = new IExecConfig({ ethProvider }); const { getIExecContract } = await iexecConfig.resolveContractsClient(); const iexecContract = getIExecContract(); @@ -288,7 +277,7 @@ export const approveAccount = async ( approvedAddress: string, nRlcAmount: ethers.BigNumberish ) => { - const ethProvider = getTestConfig(privateKey)[0]; + const [ethProvider] = await getTestConfig(privateKey); const iexecConfig = new IExecConfig({ ethProvider }); const { getIExecContract } = await iexecConfig.resolveContractsClient(); const iexecContract = getIExecContract(); diff --git a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts index 90b7bf437..9f1a911c6 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts @@ -20,9 +20,7 @@ describe('getGrantedAccess', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'protectedData should be an ethereum address' - ) + new ValidationError('protectedData should be an ethereum address') ); }); }); @@ -41,9 +39,7 @@ describe('getGrantedAccess', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedApp should be an ethereum address' - ) + new ValidationError('authorizedApp should be an ethereum address') ); }); }); @@ -62,9 +58,7 @@ describe('getGrantedAccess', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedUser should be an ethereum address' - ) + new ValidationError('authorizedUser should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts index 70060ac6f..eddbc4215 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts @@ -65,9 +65,7 @@ describe('dataProtectorCore > getProtectedData()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'owner should be an ethereum address' - ) + new ValidationError('owner should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts index 65d5f0de9..f2db897b1 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts @@ -53,9 +53,7 @@ describe('dataProtectorCore.grantAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'protectedData should be an ethereum address' - ) + new ValidationError('protectedData should be an ethereum address') ); }); }); @@ -95,9 +93,7 @@ describe('dataProtectorCore.grantAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedApp should be an ethereum address' - ) + new ValidationError('authorizedApp should be an ethereum address') ); }); }); @@ -137,9 +133,7 @@ describe('dataProtectorCore.grantAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedUser should be an ethereum address' - ) + new ValidationError('authorizedUser should be an ethereum address') ); }); }); @@ -187,7 +181,6 @@ describe('dataProtectorCore.grantAccess()', () => { ); }); }); - }); describe('When access has already been granted to this same app', () => { diff --git a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts index 364d7a030..8b8dd57d8 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/prepareBulkRequest.test.ts @@ -306,9 +306,7 @@ describe('prepareBulkRequest', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'workerpool should be an ethereum address' - ) + new ValidationError('workerpool should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts index f9e7fa7e3..69a4393ac 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processBulkRequest.test.ts @@ -112,13 +112,10 @@ describe('processBulkRequest', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'workerpool should be an ethereum address' - ) + new ValidationError('workerpool should be an ethereum address') ); }); }); - }); describe('When there is NO app orders', () => { @@ -166,5 +163,4 @@ describe('processBulkRequest', () => { ); }); }); - }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts index f812ce1e4..f595e6dd0 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts @@ -96,9 +96,7 @@ describe('processProtectedData', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'protectedData should be an ethereum address' - ) + new ValidationError('protectedData should be an ethereum address') ); }); }); @@ -140,9 +138,7 @@ describe('processProtectedData', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedApp should be an ethereum address' - ) + new ValidationError('authorizedApp should be an ethereum address') ); }); }); @@ -341,9 +337,7 @@ describe('processProtectedData', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'workerpool should be an ethereum address' - ) + new ValidationError('workerpool should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts index 05a68c48d..c5f68ec96 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/revokeAllAccess.test.ts @@ -40,9 +40,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'protectedData should be an ethereum address' - ) + new ValidationError('protectedData should be an ethereum address') ); }); }); @@ -62,9 +60,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedApp should be an ethereum address' - ) + new ValidationError('authorizedApp should be an ethereum address') ); }); }); @@ -85,9 +81,7 @@ describe('dataProtectorCore.revokeAllAccess()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'authorizedUser should be an ethereum address' - ) + new ValidationError('authorizedUser should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts b/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts index fad098989..4f430ce4d 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/transferOwnership.test.ts @@ -39,9 +39,7 @@ describe('dataProtectorCore.transferOwnership()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'protectedData should be an ethereum address' - ) + new ValidationError('protectedData should be an ethereum address') ); }); }); @@ -81,9 +79,7 @@ describe('dataProtectorCore.transferOwnership()', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError( - 'newOwner should be an ethereum address' - ) + new ValidationError('newOwner should be an ethereum address') ); }); }); diff --git a/packages/sdk/tests/utils/appOrders.ts b/packages/sdk/tests/utils/appOrders.ts index a11f4cde7..49760a4fa 100644 --- a/packages/sdk/tests/utils/appOrders.ts +++ b/packages/sdk/tests/utils/appOrders.ts @@ -19,7 +19,7 @@ export function getOneAppOrder({ withApp }: { withApp?: string } = {}) { return { order: getAppOrderObject({ withApp }), orderHash: getRandomTxHash(), - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', @@ -38,7 +38,7 @@ export const MOCK_APP_ORDER = { orders: [ { orderHash: '0xOrderHash456', - chainId: 134, + chainId: 421614, remaining: 8, status: 'completed', signer: '0xSignerAddress456', @@ -57,7 +57,7 @@ export const MOCK_APP_ORDER = { }, { orderHash: '0xOrderHash456', - chainId: 134, + chainId: 421614, remaining: 8, status: 'completed', signer: '0xSignerAddress456', @@ -95,7 +95,7 @@ export const MOCK_APP_ORDER = { }, { orderHash: '0xOrderHash456', - chainId: 134, + chainId: 421614, remaining: 8, status: 'completed', signer: '0xSignerAddress456', diff --git a/packages/sdk/tests/utils/datasetOrders.ts b/packages/sdk/tests/utils/datasetOrders.ts index 8a49361b6..92bc5837c 100644 --- a/packages/sdk/tests/utils/datasetOrders.ts +++ b/packages/sdk/tests/utils/datasetOrders.ts @@ -26,7 +26,7 @@ export function getOneDatasetOrder({ order: getDatasetOrderObject({ withDataset, withApp }), orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', @@ -60,7 +60,7 @@ export const MOCK_DATASET_ORDER = { }, orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', @@ -80,7 +80,7 @@ export const MOCK_DATASET_ORDER = { }, orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', @@ -100,7 +100,7 @@ export const MOCK_DATASET_ORDER = { }, orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', @@ -120,7 +120,7 @@ export const MOCK_DATASET_ORDER = { }, orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', diff --git a/packages/sdk/tests/utils/workerpoolOrders.ts b/packages/sdk/tests/utils/workerpoolOrders.ts index def791f12..6883facbb 100644 --- a/packages/sdk/tests/utils/workerpoolOrders.ts +++ b/packages/sdk/tests/utils/workerpoolOrders.ts @@ -27,7 +27,7 @@ export function getOneWorkerpoolOrder({ return { order: getWorkerpoolOrderObject({ withWorkerpool }), orderHash: getRandomTxHash(), - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', From 70bc83e824714660dbe3fc01ba12c9541745b607 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:45:37 +0200 Subject: [PATCH 04/11] fix!: remove default chain host from getWeb3Provider BREAKING CHANGE: `host` is now required as second positional argument of `getWeb3Provider` instead of being nested inside the options object. Removes the implicit bellecour default. --- packages/sdk/src/config/config.ts | 2 +- packages/sdk/src/utils/getWeb3Provider.ts | 6 +- packages/sdk/tests/unit/constructor.test.ts | 59 ++++++++++++++----- .../sdk/tests/unit/getWeb3Provider.test.ts | 27 ++++----- 4 files changed, 59 insertions(+), 35 deletions(-) diff --git a/packages/sdk/src/config/config.ts b/packages/sdk/src/config/config.ts index daff19696..b0f800a27 100644 --- a/packages/sdk/src/config/config.ts +++ b/packages/sdk/src/config/config.ts @@ -24,7 +24,7 @@ const CHAIN_CONFIG: Record = { // Arbitrum Sepolia 421614: { name: 'arbitrum-sepolia-testnet', - dataprotectorContractAddress: '0x168eAF6C33a77E3caD9db892452f51a5D91df621', + dataprotectorContractAddress: '0x168eaf6c33a77e3cad9db892452f51a5d91df621', subgraphUrl: 'https://thegraph.arbitrum-sepolia-testnet.iex.ec/api/subgraphs/id/5YjRPLtjS6GH6bB4yY55Qg4HzwtRGQ8TaHtGf9UBWWd', ipfsGateway: 'https://ipfs-gateway.arbitrum-sepolia-testnet.iex.ec', diff --git a/packages/sdk/src/utils/getWeb3Provider.ts b/packages/sdk/src/utils/getWeb3Provider.ts index 50427fc4f..99fa97ad6 100644 --- a/packages/sdk/src/utils/getWeb3Provider.ts +++ b/packages/sdk/src/utils/getWeb3Provider.ts @@ -4,10 +4,10 @@ import { Web3SignerProvider } from '../lib/types/index.js'; export const getWeb3Provider = ( privateKey: string, - options: { allowExperimentalNetworks?: boolean; host?: ChainId | string } = {} + host: ChainId | string, + options: { allowExperimentalNetworks?: boolean } = {} ): Web3SignerProvider => { - const chainHost = options?.host ? `${options.host}` : 'bellecour'; - return getSignerFromPrivateKey(chainHost, privateKey, { + return getSignerFromPrivateKey(`${host}`, privateKey, { allowExperimentalNetworks: options?.allowExperimentalNetworks, providers: {}, }); diff --git a/packages/sdk/tests/unit/constructor.test.ts b/packages/sdk/tests/unit/constructor.test.ts index aa90de14a..3d9610e41 100644 --- a/packages/sdk/tests/unit/constructor.test.ts +++ b/packages/sdk/tests/unit/constructor.test.ts @@ -8,17 +8,23 @@ import { IExecDataProtector, getWeb3Provider } from '../../src/index.js'; describe('IExecDataProtector()', () => { it('should use default ipfs node url when ipfsNode is NOT provided', async () => { const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey) + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ) ); await dataProtector['init'](); const ipfsNode = dataProtector['ipfsNode']; - expect(ipfsNode).toStrictEqual(getChainConfig(134).ipfsNode); + expect(ipfsNode).toStrictEqual(getChainConfig(421614).ipfsNode); }); it('should use provided ipfs node url when ipfsNode is provided', async () => { const customIpfsNode = 'https://example.com/node'; const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey), + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ), { ipfsNode: customIpfsNode, } @@ -30,17 +36,23 @@ describe('IExecDataProtector()', () => { it('should use default ipfs gateway url when ipfsGateway is NOT provided', async () => { const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey) + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ) ); await dataProtector['init'](); const ipfsGateway = dataProtector['ipfsGateway']; - expect(ipfsGateway).toStrictEqual(getChainConfig(134).ipfsGateway); + expect(ipfsGateway).toStrictEqual(getChainConfig(421614).ipfsGateway); }); it('should use default ipfs gateway url when ipfsGateway is provided', async () => { const customIpfsGateway = 'https://example.com/ipfs_gateway'; const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey), + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ), { ipfsGateway: customIpfsGateway, } @@ -52,20 +64,26 @@ describe('IExecDataProtector()', () => { it('should use default smart contract address when dataprotectorContractAddress is NOT provided', async () => { const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey) + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ) ); await dataProtector['init'](); const dataprotectorContractAddress = dataProtector['dataprotectorContractAddress']; expect(dataprotectorContractAddress).toStrictEqual( - getChainConfig(134).dataprotectorContractAddress + getChainConfig(421614).dataprotectorContractAddress ); }); it('should use provided smart contract address when dataprotectorContractAddress is provided', async () => { const customSContractAddress = Wallet.createRandom().address; const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey), + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ), { dataprotectorContractAddress: customSContractAddress, } @@ -80,17 +98,23 @@ describe('IExecDataProtector()', () => { it('should use default subgraph URL when subgraphUrl is NOT provided', async () => { const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey) + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ) ); await dataProtector['init'](); const graphQLClientUrl = dataProtector['graphQLClient']; - expect(graphQLClientUrl['url']).toBe(getChainConfig(134).subgraphUrl); + expect(graphQLClientUrl['url']).toBe(getChainConfig(421614).subgraphUrl); }); it('should use provided subgraph URL when subgraphUrl is provided', async () => { const customSubgraphUrl = 'https://example.com/custom-subgraph'; const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey), + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ), { subgraphUrl: customSubgraphUrl, } @@ -109,7 +133,10 @@ describe('IExecDataProtector()', () => { const iexecGatewayURL = 'https://custom-market-api-url.com'; const dataProtector = new IExecDataProtector( - getWeb3Provider(Wallet.createRandom().privateKey), + getWeb3Provider( + Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet' + ), { subgraphUrl: customSubgraphUrl, dataprotectorContractAddress: customSContractAddress, @@ -151,7 +178,7 @@ describe('IExecDataProtector()', () => { it('instantiates with a valid ethProvider', async () => { const wallet = Wallet.createRandom(); const dataProtector = new IExecDataProtector( - getWeb3Provider(wallet.privateKey) + getWeb3Provider(wallet.privateKey, 'arbitrum-sepolia-testnet') ); await dataProtector['init'](); expect(dataProtector).toBeInstanceOf(IExecDataProtector); @@ -161,7 +188,7 @@ describe('IExecDataProtector()', () => { const smsURL = 'https://custom-sms-url.com'; const wallet = Wallet.createRandom(); const dataProtector = new IExecDataProtector( - getWeb3Provider(wallet.privateKey), + getWeb3Provider(wallet.privateKey, 'arbitrum-sepolia-testnet'), { iexecOptions: { smsURL, @@ -192,8 +219,8 @@ describe('IExecDataProtector()', () => { describe.skip('When instantiating SDK with an experimental network', () => { const experimentalNetworkSigner = getWeb3Provider( Wallet.createRandom().privateKey, + 'arbitrum-sepolia-testnet', { - host: 421614, allowExperimentalNetworks: true, } ); diff --git a/packages/sdk/tests/unit/getWeb3Provider.test.ts b/packages/sdk/tests/unit/getWeb3Provider.test.ts index 5de0c9de6..f154da434 100644 --- a/packages/sdk/tests/unit/getWeb3Provider.test.ts +++ b/packages/sdk/tests/unit/getWeb3Provider.test.ts @@ -5,46 +5,43 @@ import { getWeb3Provider } from '../../src/index.js'; describe('getWeb3Provider()', () => { const { privateKey, address } = Wallet.createRandom(); it('should use the wallet', async () => { - const provider = getWeb3Provider(privateKey); + const provider = getWeb3Provider(privateKey, 421614); const providerAddress = await provider.getAddress(); expect(providerAddress).toBe(address); }); - it('should use bellecour by default', async () => { - const provider = getWeb3Provider(privateKey); - const network = await provider.provider.getNetwork(); - expect(network.name).toBe('bellecour'); - }); - it('should accept RPC URL as host', () => { expect( - getWeb3Provider(privateKey, { host: 'https://bellecour.iex.ec' }) + getWeb3Provider(privateKey, 'https://sepolia-rollup.arbitrum.io/rpc') ).toBeDefined(); }); it('should accept chainId as host', () => { - expect(getWeb3Provider(privateKey, { host: 134 })).toBeDefined(); + expect(getWeb3Provider(privateKey, 421614)).toBeDefined(); }); it('should accept chain name as host', () => { - expect(getWeb3Provider(privateKey, { host: 'bellecour' })).toBeDefined(); + expect( + getWeb3Provider(privateKey, 'arbitrum-sepolia-testnet') + ).toBeDefined(); }); describe.skip('When instantiating SDK with an experimental network', () => { describe('Without allowExperimentalNetworks', () => { it('should throw a configuration error', () => { expect(() => - getWeb3Provider(privateKey, { host: 'arbitrum-sepolia-testnet' }) + getWeb3Provider(privateKey, 'arbitrum-sepolia-testnet') ).toThrow('Invalid provider host name or url'); }); }); describe('With allowExperimentalNetworks: true', () => { it('should use the specified network', async () => { - const provider = getWeb3Provider(privateKey, { - host: 'arbitrum-sepolia-testnet', - allowExperimentalNetworks: true, - }); + const provider = getWeb3Provider( + privateKey, + 'arbitrum-sepolia-testnet', + { allowExperimentalNetworks: true } + ); const network = await provider.provider.getNetwork(); expect(network.name).toBe('arbitrum-sepolia'); }); From f93dede27136862e2db47c88174ffec9f831bc0a Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:03:32 +0200 Subject: [PATCH 05/11] fix!: remove default ethProvider and fix explorer link BREAKING CHANGE: ethProvider is required in the IExecDataProtectorModule constructor --- packages/sdk/src/lib/IExecDataProtector.ts | 2 +- packages/sdk/src/lib/IExecDataProtectorModule.ts | 10 ++++++++-- .../lib/dataProtectorCore/IExecDataProtectorCore.ts | 1 + .../sdk/src/lib/dataProtectorCore/protectData.ts | 5 ++++- packages/sdk/src/lib/types/internalTypes.ts | 4 ++++ packages/sdk/tests/unit/constructor.test.ts | 6 ++++-- .../unit/dataProtectorCore/protectData.test.ts | 13 +++++++++++++ 7 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/sdk/src/lib/IExecDataProtector.ts b/packages/sdk/src/lib/IExecDataProtector.ts index 57802cf3f..efe4908f8 100644 --- a/packages/sdk/src/lib/IExecDataProtector.ts +++ b/packages/sdk/src/lib/IExecDataProtector.ts @@ -10,7 +10,7 @@ class IExecDataProtector extends IExecDataProtectorModule { public core: IExecDataProtectorCore; constructor( - ethProvider?: + ethProvider: | AbstractProvider | AbstractSigner | Eip1193Provider diff --git a/packages/sdk/src/lib/IExecDataProtectorModule.ts b/packages/sdk/src/lib/IExecDataProtectorModule.ts index 4098aa92b..4a74ecea3 100644 --- a/packages/sdk/src/lib/IExecDataProtectorModule.ts +++ b/packages/sdk/src/lib/IExecDataProtectorModule.ts @@ -20,6 +20,7 @@ type EthersCompatibleProvider = | string; interface IExecDataProtectorResolvedConfig { + networkName: string; dataprotectorContractAddress: Address; graphQLClient: GraphQLClient; pocoSubgraphClient: GraphQLClient; @@ -32,6 +33,8 @@ interface IExecDataProtectorResolvedConfig { abstract class IExecDataProtectorModule { protected dataprotectorContractAddress!: Address; + protected networkName!: string; + protected graphQLClient!: GraphQLClient; protected pocoSubgraphClient!: GraphQLClient; @@ -53,16 +56,17 @@ abstract class IExecDataProtectorModule { private options: DataProtectorConfigOptions; constructor( - ethProvider?: EthersCompatibleProvider, + ethProvider: EthersCompatibleProvider, options?: DataProtectorConfigOptions ) { - this.ethProvider = ethProvider || 'bellecour'; + this.ethProvider = ethProvider; this.options = options || {}; } protected async init(): Promise { if (!this.initPromise) { this.initPromise = this.resolveConfig().then((config) => { + this.networkName = config.networkName; this.dataprotectorContractAddress = config.dataprotectorContractAddress; this.graphQLClient = config.graphQLClient; this.pocoSubgraphClient = config.pocoSubgraphClient; @@ -90,6 +94,7 @@ abstract class IExecDataProtectorModule { this.options?.ipfsGateway || chainDefaultConfig?.ipfsGateway; const defaultWorkerpool = chainDefaultConfig?.workerpoolAddress; const ipfsNode = this.options?.ipfsNode || chainDefaultConfig?.ipfsNode; + const networkName = chainDefaultConfig?.name || `unknown-chain-${chainId}`; const missing = []; if (!subgraphUrl) missing.push('subgraphUrl'); @@ -139,6 +144,7 @@ abstract class IExecDataProtectorModule { } return { + networkName, dataprotectorContractAddress: dataprotectorContractAddress.toLowerCase(), defaultWorkerpool, graphQLClient, diff --git a/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts b/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts index b7f3e88d2..2888003eb 100644 --- a/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts +++ b/packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts @@ -48,6 +48,7 @@ class IExecDataProtectorCore extends IExecDataProtectorModule { await isValidSigner(this.iexec); return protectData({ ...args, + networkName: this.networkName, dataprotectorContractAddress: this.dataprotectorContractAddress, ipfsNode: this.ipfsNode, ipfsGateway: this.ipfsGateway, diff --git a/packages/sdk/src/lib/dataProtectorCore/protectData.ts b/packages/sdk/src/lib/dataProtectorCore/protectData.ts index cd12fa731..27f314776 100644 --- a/packages/sdk/src/lib/dataProtectorCore/protectData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/protectData.ts @@ -35,6 +35,7 @@ import { ArweaveUploadConsumer, DataProtectorContractConsumer, IExecConsumer, + NetworkNameConsumer, } from '../types/internalTypes.js'; import { getDataProtectorCoreContract } from './smartContract/getDataProtectorCoreContract.js'; @@ -47,6 +48,7 @@ export const protectData = async ({ dataprotectorContractAddress, name = DEFAULT_DATA_NAME, uploadMode = 'ipfs', + networkName, ipfsNode, ipfsGateway, arweaveUploadApi, @@ -56,6 +58,7 @@ export const protectData = async ({ DataProtectorContractConsumer & IpfsNodeAndGateway & ArweaveUploadConsumer & + NetworkNameConsumer & ProtectDataParams): Promise => { const vName = stringSchema().label('name').validateSync(name); const vUploadMode = stringSchema() @@ -249,7 +252,7 @@ export const protectData = async ({ isDone: true, payload: { address: protectedDataAddress, - explorerUrl: `https://explorer.iex.ec/bellecour/dataset/${protectedDataAddress}`, + explorerUrl: `https://explorer.iex.ec/${networkName}/dataset/${protectedDataAddress}`, owner: ownerAddress, creationTimestamp: String(creationTimestamp), txHash, diff --git a/packages/sdk/src/lib/types/internalTypes.ts b/packages/sdk/src/lib/types/internalTypes.ts index 1f1d8cc53..d7a41a7a7 100644 --- a/packages/sdk/src/lib/types/internalTypes.ts +++ b/packages/sdk/src/lib/types/internalTypes.ts @@ -21,3 +21,7 @@ export type SubgraphConsumer = { export type PocoSubgraphConsumer = { pocoSubgraphClient: GraphQLClient; }; + +export type NetworkNameConsumer = { + networkName: string; +}; diff --git a/packages/sdk/tests/unit/constructor.test.ts b/packages/sdk/tests/unit/constructor.test.ts index 3d9610e41..b421e5d5a 100644 --- a/packages/sdk/tests/unit/constructor.test.ts +++ b/packages/sdk/tests/unit/constructor.test.ts @@ -171,7 +171,7 @@ describe('IExecDataProtector()', () => { const invalidProvider: any = {}; const dataProtector = new IExecDataProtector(invalidProvider); await expect(dataProtector['init']()).rejects.toThrow( - 'Unsupported ethProvider: Invalid ethProvider: Unsupported provider' + 'Invalid ethProvider: Unsupported provider' ); }); @@ -203,7 +203,9 @@ describe('IExecDataProtector()', () => { describe('When instantiating SDK without a signer', () => { describe('When calling a write method', () => { it('should throw the corresponding exception', async () => { - const dataProtector = new IExecDataProtector(); + const dataProtector = new IExecDataProtector( + 'arbitrum-sepolia-testnet' + ); await dataProtector['init'](); await expect( dataProtector.core.protectData({ diff --git a/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts index d735eccde..c342a48b8 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts @@ -173,6 +173,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', name: 'Test', data: { myData: 'Test' }, ipfsNode: invalidIpfsNodeUrl, @@ -193,6 +194,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', name: 'Test', data: { myData: 'Test' }, ipfsGateway: invalidIpfsGatewayUrl, @@ -210,6 +212,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', name: 'Test', data: { 'invalid.key': 'Test' }, }) @@ -230,6 +233,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', name: 'Test', data: { tooLargeBigint: BigInt( @@ -301,6 +305,7 @@ describe('protectData()', () => { const result = await protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data, name: DATA_NAME, @@ -326,6 +331,7 @@ describe('protectData()', () => { await protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', data: { foo: 'bar' }, onStatusUpdate: onStatusUpdateMock, }); @@ -414,6 +420,7 @@ describe('protectData()', () => { const data = await protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data: { doNotUse: 'test' }, }); @@ -431,6 +438,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data: { foo: 'bar' }, }) @@ -471,6 +479,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data: { foo: 'bar' }, }) @@ -496,6 +505,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data: { foo: 'bar' }, }) @@ -560,6 +570,7 @@ describe('protectData()', () => { const result = await protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data, name: DATA_NAME, @@ -586,6 +597,7 @@ describe('protectData()', () => { await protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', data: { foo: 'bar' }, uploadMode: 'arweave', onStatusUpdate: onStatusUpdateMock, @@ -682,6 +694,7 @@ describe('protectData()', () => { protectData({ iexec, dataprotectorContractAddress: getRandomAddress(), + networkName: 'test-network', ...protectDataDefaultArgs, data: { foo: 'bar' }, uploadMode: 'arweave', From 5674e8a2e0f1418723ba9de92650cdc700ad56b5 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:12:25 +0200 Subject: [PATCH 06/11] fix!: remove Bellecour chain support BREAKING CHANGE: bellecour chain is no longer supported --- packages/sdk/src/config/config.ts | 11 ----------- .../sdk/src/lib/dataProtectorCore/protectData.ts | 6 ++---- packages/sdk/src/utils/getChainId.ts | 16 +++++----------- .../dataProtectorCore/getGrantedAccess.test.ts | 2 +- .../unit/dataProtectorCore/protectData.test.ts | 8 ++++---- .../utils/mockAllForProcessProtectedData.ts | 2 +- 6 files changed, 13 insertions(+), 32 deletions(-) diff --git a/packages/sdk/src/config/config.ts b/packages/sdk/src/config/config.ts index b0f800a27..9d2c96e50 100644 --- a/packages/sdk/src/config/config.ts +++ b/packages/sdk/src/config/config.ts @@ -11,16 +11,6 @@ export interface ChainConfig { } const CHAIN_CONFIG: Record = { - // Bellecour - 134: { - name: 'bellecour', - dataprotectorContractAddress: '0x3a4ab33f3d605e75b6d00a32a0fa55c3628f6a59', - subgraphUrl: - 'https://thegraph.iex.ec/subgraphs/name/bellecour/dataprotector-v2', - ipfsGateway: 'https://ipfs-gateway.v8-bellecour.iex.ec', - ipfsNode: 'https://ipfs-upload.v8-bellecour.iex.ec', - workerpoolAddress: 'prod-v8-bellecour.main.pools.iexec.eth', - }, // Arbitrum Sepolia 421614: { name: 'arbitrum-sepolia-testnet', @@ -54,7 +44,6 @@ export const getChainConfig = ( return config; }; -export const DEFAULT_CHAIN_ID = 134; export const DEFAULT_ARWEAVE_UPLOAD_API = 'https://arweave-api.iex.ec'; export const DEFAULT_ARWEAVE_GATEWAY = 'https://arweave.net'; export const ARWEAVE_FREE_UPLOAD_MAX_SIZE = 100 * 1024; // 100kb diff --git a/packages/sdk/src/lib/dataProtectorCore/protectData.ts b/packages/sdk/src/lib/dataProtectorCore/protectData.ts index 27f314776..48f9e9401 100644 --- a/packages/sdk/src/lib/dataProtectorCore/protectData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/protectData.ts @@ -206,8 +206,7 @@ export const protectData = async ({ }); } - const { provider, signer, txOptions } = - await iexec.config.resolveContractsClient(); + const { provider, signer } = await iexec.config.resolveContractsClient(); const ownerAddress = await signer.getAddress(); @@ -225,8 +224,7 @@ export const protectData = async ({ vName, JSON.stringify(schema), multiaddrBytes, - checksum, - txOptions + checksum ) .then((tx) => tx.wait()) .catch((e: Error) => { diff --git a/packages/sdk/src/utils/getChainId.ts b/packages/sdk/src/utils/getChainId.ts index 62779d36a..8bbd99072 100644 --- a/packages/sdk/src/utils/getChainId.ts +++ b/packages/sdk/src/utils/getChainId.ts @@ -1,6 +1,5 @@ import { AbstractProvider, AbstractSigner, Eip1193Provider } from 'ethers'; import { IExecNetworkModule } from 'iexec'; -import { DEFAULT_CHAIN_ID } from '../config/config.js'; type EthersCompatibleProvider = | string @@ -11,14 +10,9 @@ type EthersCompatibleProvider = export async function getChainIdFromProvider( ethProvider: EthersCompatibleProvider ): Promise { - try { - const networkModule = new IExecNetworkModule({ - ethProvider, - }); - const { chainId } = await networkModule.getNetwork(); - return Number(chainId); - } catch (e) { - console.warn('Failed to detect chainId:', e); - } - return DEFAULT_CHAIN_ID; + const networkModule = new IExecNetworkModule({ + ethProvider, + }); + const { chainId } = await networkModule.getNetwork(); + return Number(chainId); } diff --git a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts index 9f1a911c6..d05bd7237 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getGrantedAccess.test.ts @@ -210,7 +210,7 @@ describe('getGrantedAccess', () => { }, orderHash: '0x396392835c2cbe933023dd28a3d6eedceb21c52b1dba199835a6f24cc75e7685', - chainId: 134, + chainId: 421614, publicationTimestamp: '2023-06-15T16:39:22.713Z', signer: '0xD52C27CC2c7D3fb5BA4440ffa825c12EA5658D60', status: 'open', diff --git a/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts index c342a48b8..6f31aca99 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts @@ -36,9 +36,9 @@ jest.unstable_mockModule('../../../src/utils/getEventFromLogs.js', () => ({ })); const protectDataDefaultArgs = { - contractAddress: getChainConfig(134).dataprotectorContractAddress, - ipfsNode: getChainConfig(134).ipfsNode, - ipfsGateway: getChainConfig(134).ipfsGateway, + contractAddress: getChainConfig(421614).dataprotectorContractAddress, + ipfsNode: getChainConfig(421614).ipfsNode, + ipfsGateway: getChainConfig(421614).ipfsGateway, }; describe('protectData()', () => { @@ -51,7 +51,7 @@ describe('protectData()', () => { wallet = Wallet.createRandom(); iexec = new IExec({ ethProvider: utils.getSignerFromPrivateKey( - 'https://bellecour.iex.ec', + 'arbitrum-sepolia-testnet', wallet.privateKey ), }); diff --git a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts index b020c3dc9..5f4f730ca 100644 --- a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts +++ b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts @@ -78,7 +78,7 @@ export function mockAllForProcessProtectedData({ network: { getNetwork: jest .fn<() => Promise>() - .mockResolvedValue({ chainId: 134 }), + .mockResolvedValue({ chainId: 421614 }), }, }; } From 2baf16d9ddae447b077f5baac9025277f2d93830 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:34:39 +0200 Subject: [PATCH 07/11] fix: set missing default values for max prices (0) in processProtectedData --- packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts index 6a1ae8159..60682e535 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts @@ -79,12 +79,15 @@ export const processProtectedData = async < .validateSync(userWhitelist); const vDataMaxPrice = positiveNumberSchema() .label('dataMaxPrice') + .default(0) .validateSync(dataMaxPrice); const vAppMaxPrice = positiveNumberSchema() .label('appMaxPrice') + .default(0) .validateSync(appMaxPrice); const vWorkerpoolMaxPrice = positiveNumberSchema() .label('workerpoolMaxPrice') + .default(0) .validateSync(workerpoolMaxPrice); const vPath = stringSchema().label('path').validateSync(path); const vInputFiles = urlArraySchema() From f3db7c317861caaeee49a05460c74239cccf4a1f Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:36:31 +0200 Subject: [PATCH 08/11] chore: typing cleanup --- .../tests/unit/dataProtectorCore/getProtectedData.test.ts | 6 ++++-- .../sdk/tests/unit/dataProtectorCore/grantAccess.test.ts | 3 --- .../processProtectedData/processProtectedData.test.ts | 2 +- packages/sdk/tests/unit/services/arweave.test.ts | 2 +- packages/sdk/tests/unit/utils/formatGrantedAccess.test.ts | 1 + packages/sdk/tests/unit/utils/getMultiaddrAsString.test.ts | 1 + packages/sdk/tests/utils/mockAllForProcessProtectedData.ts | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts index eddbc4215..e1116565a 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/getProtectedData.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, jest } from '@jest/globals'; +import { afterAll, beforeAll, describe, expect, it, jest } from '@jest/globals'; import { getProtectedData } from '../../../src/lib/dataProtectorCore/getProtectedData.js'; import { ProtectedDatasGraphQLResponse } from '../../../src/lib/types/graphQLTypes.js'; import { ValidationError } from '../../../src/utils/errors.js'; @@ -335,7 +335,9 @@ describe('dataProtectorCore > getProtectedData()', () => { }); describe('requiredSchema', () => { - let fetchProtectedDataFromSubgraphSpy; + let fetchProtectedDataFromSubgraphSpy: jest.Mock< + () => Promise + >; let graphQLClient; beforeAll(() => { diff --git a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts index f2db897b1..98b15fba8 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/grantAccess.test.ts @@ -228,9 +228,6 @@ describe('dataProtectorCore.grantAccess()', () => { }, app: { checkDeployedApp: jest.fn().mockReturnValue(true), - showApp: jest.fn().mockResolvedValue({ - app: { appMREnclave: '{ "framework": "SCONE" }' }, - }), }, order: { createDatasetorder: jest.fn().mockResolvedValue({ diff --git a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts index f595e6dd0..4c5cfef25 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, jest } from '@jest/globals'; +import { beforeAll, describe, expect, it, jest } from '@jest/globals'; import { ZeroAddress } from 'ethers'; import { Address } from 'iexec'; import { ValidationError } from 'yup'; diff --git a/packages/sdk/tests/unit/services/arweave.test.ts b/packages/sdk/tests/unit/services/arweave.test.ts index 2abb94233..976f724cb 100644 --- a/packages/sdk/tests/unit/services/arweave.test.ts +++ b/packages/sdk/tests/unit/services/arweave.test.ts @@ -1,4 +1,4 @@ -import { describe, it } from '@jest/globals'; +import { describe, expect, it } from '@jest/globals'; import { ARWEAVE_FREE_UPLOAD_MAX_SIZE } from '../../../src/config/config.js'; import * as arweave from '../../../src/services/arweave.js'; diff --git a/packages/sdk/tests/unit/utils/formatGrantedAccess.test.ts b/packages/sdk/tests/unit/utils/formatGrantedAccess.test.ts index 824c2d44b..c4f9c7cee 100644 --- a/packages/sdk/tests/unit/utils/formatGrantedAccess.test.ts +++ b/packages/sdk/tests/unit/utils/formatGrantedAccess.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from '@jest/globals'; import { formatGrantedAccess } from '../../../src/utils/formatGrantedAccess.js'; describe('formatGrantedAccess', () => { diff --git a/packages/sdk/tests/unit/utils/getMultiaddrAsString.test.ts b/packages/sdk/tests/unit/utils/getMultiaddrAsString.test.ts index 24f01859c..eb57f7c75 100644 --- a/packages/sdk/tests/unit/utils/getMultiaddrAsString.test.ts +++ b/packages/sdk/tests/unit/utils/getMultiaddrAsString.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from '@jest/globals'; import { getMultiaddrAsString } from '../../../src/utils/getMultiaddrAsString.js'; describe('getMultiaddrAsString', () => { diff --git a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts index 5f4f730ca..dee4aa4ea 100644 --- a/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts +++ b/packages/sdk/tests/utils/mockAllForProcessProtectedData.ts @@ -1,6 +1,6 @@ import { jest } from '@jest/globals'; -import { BN } from 'iexec/utils'; import { Address, Dealid } from 'iexec'; +import { BN } from 'iexec/utils'; import { getRandomAddress, getRandomTxHash, From 13054284a817cc2494fb86426807d0b81036378c Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:46:24 +0200 Subject: [PATCH 09/11] chore: update iexec deps --- packages/sdk/package-lock.json | 8 ++++---- packages/sdk/package.json | 2 +- packages/sdk/src/lib/types/commonTypes.ts | 4 ++-- packages/sdk/src/utils/getWeb3Provider.ts | 1 - packages/sdk/tests/test-utils.ts | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/sdk/package-lock.json b/packages/sdk/package-lock.json index 0591ac87b..387087996 100644 --- a/packages/sdk/package-lock.json +++ b/packages/sdk/package-lock.json @@ -18,7 +18,7 @@ "debug": "^4.3.4", "ethers": "^6.13.2", "graphql-request": "^6.0.0", - "iexec": "^8.24.0", + "iexec": "^9.0.0", "jszip": "^3.7.1", "kubo-rpc-client": "^5.4.1", "magic-bytes.js": "^1.0.15", @@ -5770,9 +5770,9 @@ ] }, "node_modules/iexec": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/iexec/-/iexec-8.24.0.tgz", - "integrity": "sha512-XMi+kZlRHPB5prubA7PQvhEmKxENN/5P0+gfe96eKKUWZSb3qllzi14btRE/MEmUXwsQok9kpIOq9IajUY8VQQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/iexec/-/iexec-9.0.0.tgz", + "integrity": "sha512-6Rh8GvxBUxuElBFUatn55RG0PdoQBLxYW73hB1LrBA4kycea526qJK5ut7Qi2xF2K5xXXYLwH8QdeioYEC6SuQ==", "license": "Apache-2.0", "dependencies": { "@multiformats/multiaddr": "^13.0.1", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 489c0f88d..9fddc686a 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -61,7 +61,7 @@ "debug": "^4.3.4", "ethers": "^6.13.2", "graphql-request": "^6.0.0", - "iexec": "^8.24.0", + "iexec": "^9.0.0", "jszip": "^3.7.1", "kubo-rpc-client": "^5.4.1", "magic-bytes.js": "^1.0.15", diff --git a/packages/sdk/src/lib/types/commonTypes.ts b/packages/sdk/src/lib/types/commonTypes.ts index 08aadeff1..6b0283dd4 100644 --- a/packages/sdk/src/lib/types/commonTypes.ts +++ b/packages/sdk/src/lib/types/commonTypes.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { EnhancedWallet } from 'iexec'; +import { AbstractSigner } from 'ethers'; import { IExecConfigOptions } from 'iexec/IExecConfig'; export type { Taskid } from 'iexec'; @@ -10,7 +10,7 @@ export type { Taskid } from 'iexec'; export type Address = string; -export type Web3SignerProvider = EnhancedWallet; +export type Web3SignerProvider = AbstractSigner; export type OnStatusUpdateFn = (params: { title: T; diff --git a/packages/sdk/src/utils/getWeb3Provider.ts b/packages/sdk/src/utils/getWeb3Provider.ts index 99fa97ad6..bec528e72 100644 --- a/packages/sdk/src/utils/getWeb3Provider.ts +++ b/packages/sdk/src/utils/getWeb3Provider.ts @@ -9,6 +9,5 @@ export const getWeb3Provider = ( ): Web3SignerProvider => { return getSignerFromPrivateKey(`${host}`, privateKey, { allowExperimentalNetworks: options?.allowExperimentalNetworks, - providers: {}, }); }; diff --git a/packages/sdk/tests/test-utils.ts b/packages/sdk/tests/test-utils.ts index b0cf81745..eb6606ea8 100644 --- a/packages/sdk/tests/test-utils.ts +++ b/packages/sdk/tests/test-utils.ts @@ -95,7 +95,7 @@ export const deployRandomApp = async (params: { const ethProvider = params.ethProvider; const iexecAppModule = new IExecAppModule({ ethProvider }); const { address } = await iexecAppModule.deployApp({ - owner: ethProvider.address, + owner: await ethProvider.getAddress(), name: 'test-do-not-use', type: 'DOCKER', multiaddr: 'foo/bar:baz', From b9e811f514d0758b07545af93057349c3be5cc89 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:54:19 +0200 Subject: [PATCH 10/11] fix: updates label for processProtectedData app validation --- .../sdk/src/lib/dataProtectorCore/processProtectedData.ts | 5 +---- .../processProtectedData/processProtectedData.test.ts | 6 ++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts index 60682e535..2ca33f4d0 100644 --- a/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts +++ b/packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts @@ -70,10 +70,7 @@ export const processProtectedData = async < .required() .label('protectedData') .validateSync(protectedData); - const vApp = addressSchema() - .required() - .label('authorizedApp') - .validateSync(app); + const vApp = addressSchema().required().label('app').validateSync(app); const vUserWhitelist = addressSchema() .label('userWhitelist') .validateSync(userWhitelist); diff --git a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts index 4c5cfef25..3b47db22b 100644 --- a/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts +++ b/packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts @@ -116,9 +116,7 @@ describe('processProtectedData', () => { app: missingAppAddress, }) // --- THEN - ).rejects.toThrow( - new ValidationError(getRequiredFieldMessage('authorizedApp')) - ); + ).rejects.toThrow(new ValidationError(getRequiredFieldMessage('app'))); }); }); @@ -138,7 +136,7 @@ describe('processProtectedData', () => { }) // --- THEN ).rejects.toThrow( - new ValidationError('authorizedApp should be an ethereum address') + new ValidationError('app should be an ethereum address') ); }); }); From e8d2b59212045f5d917484154dd273812e898197 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:01:22 +0200 Subject: [PATCH 11/11] refactor: avoid side effect on input param (sort array) --- packages/sdk/src/utils/processProtectedData.models.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/src/utils/processProtectedData.models.ts b/packages/sdk/src/utils/processProtectedData.models.ts index 318d8e0d1..dc2182276 100644 --- a/packages/sdk/src/utils/processProtectedData.models.ts +++ b/packages/sdk/src/utils/processProtectedData.models.ts @@ -11,7 +11,7 @@ export function filterWorkerpoolOrders({ return null; } - const [cheapestOrder] = workerpoolOrders.sort( + const [cheapestOrder] = [...workerpoolOrders].sort( (order1, order2) => order1.order.workerpoolprice - order2.order.workerpoolprice );