From 25066caff5d665622128a8bb057ce0d17670963f Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 08:42:07 +0300 Subject: [PATCH 01/17] feat: add isPSConfigured property to OceanNodeConfig and update related status handling --- src/@types/OceanNode.ts | 2 ++ src/OceanNode.ts | 2 ++ src/components/core/utils/statusHandler.ts | 2 ++ src/utils/config/builder.ts | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/@types/OceanNode.ts b/src/@types/OceanNode.ts index 2270ba775..d6582fa7a 100644 --- a/src/@types/OceanNode.ts +++ b/src/@types/OceanNode.ts @@ -143,6 +143,7 @@ export interface OceanNodeConfig { httpCertPath?: string httpKeyPath?: string enableBenchmark?: boolean + isPSConfigured: boolean persistentStorage?: PersistentStorageConfig } @@ -185,6 +186,7 @@ export interface OceanNodeStatus { version: string http: boolean p2p: boolean + isPSConfigured: boolean provider: OceanNodeProvider[] indexer: OceanNodeIndexer[] escrowAddress: AddressPerChain diff --git a/src/OceanNode.ts b/src/OceanNode.ts index 4e23fedbe..8b0b6735d 100644 --- a/src/OceanNode.ts +++ b/src/OceanNode.ts @@ -23,6 +23,7 @@ import { createPersistentStorage } from './components/persistentStorage/createPe import { PersistentStorageFactory } from './components/persistentStorage/PersistentStorageFactory.js' import { isAddress, FallbackProvider, ethers } from 'ethers' import { create256Hash } from './utils/crypt.js' +import { isPolicyServerConfigured } from './utils/config.js' export interface RequestLimiter { requester: string | string[] // IP address or peer ID @@ -255,6 +256,7 @@ export class OceanNode { } public getConfig(): OceanNodeConfig { + this.config.isPSConfigured = isPolicyServerConfigured() return this.config } diff --git a/src/components/core/utils/statusHandler.ts b/src/components/core/utils/statusHandler.ts index 2e0d667fd..432dfd627 100644 --- a/src/components/core/utils/statusHandler.ts +++ b/src/components/core/utils/statusHandler.ts @@ -128,6 +128,7 @@ export async function status( version: getPackageVersion(), http: config.hasHttp, p2p: config.hasP2P, + isPSConfigured: config.isPSConfigured, provider: [], indexer: [], escrowAddress: {}, @@ -152,6 +153,7 @@ export async function status( nodeStatus.platform.freemem = os.freemem() nodeStatus.platform.loadavg = os.loadavg() nodeStatus.uptime = process.uptime() + nodeStatus.isPSConfigured = config.isPSConfigured // depends on request if (detailed) { diff --git a/src/utils/config/builder.ts b/src/utils/config/builder.ts index 0fc042b86..11f808ac5 100644 --- a/src/utils/config/builder.ts +++ b/src/utils/config/builder.ts @@ -20,6 +20,7 @@ import { CONFIG_LOGGER } from '../logging/common.js' import { LOG_LEVELS_STR, GENERIC_EMOJIS } from '../logging/Logger.js' import { OceanNodeConfigSchema } from './schemas.js' import { ENV_TO_CONFIG_MAPPING } from './constants.js' +import { isPolicyServerConfigured } from '../config.js' import { fileURLToPath } from 'url' import lodash from 'lodash' @@ -281,6 +282,7 @@ export function buildMergedConfig(): OceanNodeConfig { config.c2dClusters = buildC2DClusters( config.dockerComputeEnvironments as C2DDockerConfig[] ) + config.isPSConfigured = isPolicyServerConfigured() return config as OceanNodeConfig } From 05efc0852d32215c894376b0776682b321b307d6 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 12:41:43 +0300 Subject: [PATCH 02/17] chore: Add credentials verification in /initialize endpoint 150 --- src/components/core/handler/feesHandler.ts | 139 ++++++++++++++++++++- 1 file changed, 136 insertions(+), 3 deletions(-) diff --git a/src/components/core/handler/feesHandler.ts b/src/components/core/handler/feesHandler.ts index 0dbd44292..6090a46a6 100644 --- a/src/components/core/handler/feesHandler.ts +++ b/src/components/core/handler/feesHandler.ts @@ -16,7 +16,10 @@ import { ProviderInitialize } from '../../../@types/Fees.js' import { getNonce } from '../utils/nonceHandler.js' import { streamToString } from '../../../utils/util.js' import { isOrderingAllowedForAsset } from './downloadHandler.js' -import { DDOManager } from '@oceanprotocol/ddo-js' +import { Credentials, DDOManager } from '@oceanprotocol/ddo-js' +import { checkCredentials } from '../../../utils/credentials.js' +import { isPolicyServerConfigured } from '../../../utils/index.js' +import { PolicyServer } from '../../policyServer/index.js' export class FeesHandler extends CommandHandler { validate(command: GetFeesCommand): ValidateParams { @@ -60,14 +63,144 @@ export class FeesHandler extends CommandHandler { } } const ddoInstance = DDOManager.getDDOClass(ddo) - const { services } = ddoInstance.getDDOFields() as any + const { + chainId: ddoChainId, + credentials, + services + } = ddoInstance.getDDOFields() as any const service = services.find((what: any) => what.id === task.serviceId) if (!service) { errorMsg = 'Invalid serviceId' } - if (service.type === 'compute') { + if (service?.type === 'compute') { errorMsg = 'Use the initializeCompute endpoint to initialize compute jobs' } + + if (errorMsg) { + PROVIDER_LOGGER.logMessageWithEmoji( + errorMsg, + true, + GENERIC_EMOJIS.EMOJI_CROSS_MARK, + LOG_LEVELS_STR.LEVEL_ERROR + ) + return { + stream: null, + status: { + httpStatus: 500, + error: errorMsg + } + } + } + + const policyServer = new PolicyServer() + if (credentials || service.credentials) { + if (!task.consumerAddress) { + return { + stream: null, + status: { + httpStatus: 400, + error: 'consumerAddress is required to check credentials' + } + } + } + + let signer + if (!isPolicyServerConfigured()) { + const oceanNode = this.getOceanNode() + const supportedNetwork = oceanNode.getConfig().supportedNetworks?.[ddoChainId] + if (!supportedNetwork) { + return { + stream: null, + status: { + httpStatus: 400, + error: `Fees handler: Unsupported chain id ${ddoChainId}` + } + } + } + + const blockchain = oceanNode.getBlockchain(supportedNetwork.chainId) + if (!blockchain) { + return { + stream: null, + status: { + httpStatus: 400, + error: `Fees handler: Blockchain instance not available for chain ${supportedNetwork.chainId}` + } + } + } + + const { ready, error } = await blockchain.isNetworkReady() + if (!ready) { + return { + stream: null, + status: { + httpStatus: 400, + error: `Fees handler: ${error}` + } + } + } + signer = await blockchain.getSigner() + } + + let accessGrantedDDOLevel = false + if (credentials) { + if (isPolicyServerConfigured()) { + const response = await policyServer.initializePSVerification( + ddoInstance.getDid(), + ddo, + task.serviceId, + task.consumerAddress, + task.policyServer + ) + accessGrantedDDOLevel = response.success + } else { + accessGrantedDDOLevel = await checkCredentials( + task.consumerAddress, + credentials as Credentials, + signer + ) + } + } + + if (credentials && !accessGrantedDDOLevel) { + const error = `Error: Access to asset ${ddoInstance.getDid()} was denied` + PROVIDER_LOGGER.error(error) + return { + stream: null, + status: { httpStatus: 403, error } + } + } + + if (service.credentials) { + let accessGrantedServiceLevel: boolean + if (isPolicyServerConfigured()) { + const response = await policyServer.initializePSVerification( + ddoInstance.getDid(), + ddo, + service.id, + task.consumerAddress, + task.policyServer + ) + accessGrantedServiceLevel = accessGrantedDDOLevel || response.success + } else { + accessGrantedServiceLevel = await checkCredentials( + task.consumerAddress, + service.credentials, + signer + ) + } + + if (!accessGrantedServiceLevel) { + const error = `Error: Access to service with id ${service.id} was denied` + PROVIDER_LOGGER.error(error) + return { + stream: null, + status: { httpStatus: 403, error } + } + } + } + } + const now = new Date().getTime() / 1000 let validUntil = service.timeout === 0 ? 0 : now + service.timeout // first, make it service default if (task.validUntil && !isNaN(task.validUntil)) { From ce84918c22d5bc0e7c7bb31f470b73316ea182b9 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 13:47:59 +0300 Subject: [PATCH 03/17] fix: fix --- src/utils/credentials.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index b21c25f21..f727d553e 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -163,6 +163,10 @@ export async function checkSingleCredential( consumerAddress: string, signer: Signer | null ): Promise { + if (!credential || typeof credential.type !== 'string') { + CORE_LOGGER.warn('Credential is missing a valid string type') + return null + } const credentialType = credential.type.toLowerCase() // ======================================== @@ -172,20 +176,27 @@ export async function checkSingleCredential( // Type assertion since we know it's address type const addressCredential = credential as any - if (!isDefined(addressCredential.values) || addressCredential.values.length === 0) { + if ( + !Array.isArray(addressCredential.values) || + addressCredential.values.length === 0 + ) { return false } + const normalizedValues = addressCredential.values + .filter((value: unknown): value is string => typeof value === 'string') + .map((value: string) => value.toLowerCase()) + + if (normalizedValues.length !== addressCredential.values.length) { + CORE_LOGGER.warn('Address credential contains non-string values; ignoring them') + } + // Check for wildcard (*) - const hasWildcard = addressCredential.values.some( - (value: string) => value.toLowerCase() === '*' - ) - if (hasWildcard) { + if (normalizedValues.includes('*')) { return true } // Check if address is in the list - const normalizedValues = addressCredential.values.map((v: string) => v.toLowerCase()) return normalizedValues.includes(consumerAddress.toLowerCase()) } From 6deac0d6c91820cd7614aea00bf529ba138fdcfb Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 13:56:28 +0300 Subject: [PATCH 04/17] fix: add logs --- src/components/core/handler/feesHandler.ts | 3 +++ src/utils/credentials.ts | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/core/handler/feesHandler.ts b/src/components/core/handler/feesHandler.ts index 6090a46a6..ab9f2e817 100644 --- a/src/components/core/handler/feesHandler.ts +++ b/src/components/core/handler/feesHandler.ts @@ -162,6 +162,9 @@ export class FeesHandler extends CommandHandler { } } + PROVIDER_LOGGER.info(`credentials: ${JSON.stringify(credentials)}`) + PROVIDER_LOGGER.info(`accessGrantedDDOLevel: ${accessGrantedDDOLevel}`) + if (credentials && !accessGrantedDDOLevel) { const error = `Error: Access to asset ${ddoInstance.getDid()} was denied` PROVIDER_LOGGER.error(error) diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index f727d553e..904c5865c 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -32,6 +32,7 @@ export async function checkCredentials( signer: Signer ): Promise { // If credentials are undefined or empty, allow access + CORE_LOGGER.info(`Checking credentials for consumer address: ${consumerAddress}`) if (!isDefined(credentials)) { return true } @@ -52,6 +53,7 @@ export async function checkCredentials( matchDeny, 'deny' ) + CORE_LOGGER.info(`Deny evaluation result: ${JSON.stringify(denyResult)}`) // If evaluation says to deny, return false if (denyResult.shouldDeny) { @@ -73,7 +75,7 @@ export async function checkCredentials( matchAllow, 'allow' ) - + CORE_LOGGER.info(`Allow evaluation result: ${JSON.stringify(allowResult)}`) return allowResult.shouldAllow } From 4e4413ee6ab92c540bf8e477be7957aa87befb6a Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 13:59:41 +0300 Subject: [PATCH 05/17] fix: logs --- src/components/core/handler/feesHandler.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/core/handler/feesHandler.ts b/src/components/core/handler/feesHandler.ts index ab9f2e817..4f1044f99 100644 --- a/src/components/core/handler/feesHandler.ts +++ b/src/components/core/handler/feesHandler.ts @@ -145,6 +145,9 @@ export class FeesHandler extends CommandHandler { let accessGrantedDDOLevel = false if (credentials) { if (isPolicyServerConfigured()) { + PROVIDER_LOGGER.info( + `Checking credentials for consumer address on policy server: ${task.consumerAddress}` + ) const response = await policyServer.initializePSVerification( ddoInstance.getDid(), ddo, @@ -154,6 +157,9 @@ export class FeesHandler extends CommandHandler { ) accessGrantedDDOLevel = response.success } else { + PROVIDER_LOGGER.info( + `Checking credentials for consumer address: ${task.consumerAddress}` + ) accessGrantedDDOLevel = await checkCredentials( task.consumerAddress, credentials as Credentials, From bf99d4423d1d17bbee0614733a8f89eb79b0a0b3 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 14:03:23 +0300 Subject: [PATCH 06/17] fix: logs --- src/components/core/handler/feesHandler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/core/handler/feesHandler.ts b/src/components/core/handler/feesHandler.ts index 4f1044f99..7d719c5a7 100644 --- a/src/components/core/handler/feesHandler.ts +++ b/src/components/core/handler/feesHandler.ts @@ -143,6 +143,9 @@ export class FeesHandler extends CommandHandler { } let accessGrantedDDOLevel = false + PROVIDER_LOGGER.info( + `Checking credentials for consumer address: ${task.consumerAddress} AND credentials: ${JSON.stringify(credentials)}` + ) if (credentials) { if (isPolicyServerConfigured()) { PROVIDER_LOGGER.info( From 6d0385b494fdcd0c2f94e6ec97f63666aeb759ed Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 14:10:35 +0300 Subject: [PATCH 07/17] fix: logs --- src/utils/credentials.ts | 52 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index 904c5865c..84ad25b50 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -67,7 +67,11 @@ export async function checkCredentials( // ======================================== // STEP 2: Check ALLOW list // ======================================== + CORE_LOGGER.info( + `isDefined(credentials.allow): ${isDefined(credentials.allow)}, credentials.allow.length: ${credentials.allow?.length ?? 0}` + ) if (isDefined(credentials.allow) && credentials.allow.length > 0) { + CORE_LOGGER.info(`Allow evaluation started for consumer address: ${consumerAddress}`) const allowResult = await evaluateCredentialList( credentials.allow, normalizedAddress, @@ -94,8 +98,20 @@ async function evaluateCredentialList( listType: 'allow' | 'deny' ): Promise<{ shouldAllow: boolean; shouldDeny: boolean }> { const matchResults: boolean[] = [] - for (const credential of credentialList) { + CORE_LOGGER.info( + `Evaluating ${listType} credential list: count=${credentialList.length}, matchRule=${matchRule}` + ) + + for (const [index, credential] of credentialList.entries()) { + CORE_LOGGER.info( + `Evaluating ${listType} credential at index ${index}: type=${String( + credential?.type + )}` + ) const matchResult = await checkSingleCredential(credential, consumerAddress, signer) + CORE_LOGGER.info( + `${listType} credential at index ${index} matched: ${String(matchResult)}` + ) if (matchResult === null) { // Unknown or unsupported credential type @@ -116,6 +132,7 @@ async function evaluateCredentialList( // No valid credential checks were performed if (matchResults.length === 0) { + CORE_LOGGER.info(`No valid results produced for ${listType} credentials`) if (listType === 'allow') { // No valid allow rules means deny return { shouldAllow: false, shouldDeny: false } @@ -136,6 +153,9 @@ async function evaluateCredentialList( // If ALL rules match, deny shouldDeny = matchResults.every((r) => r === true) } + CORE_LOGGER.info( + `Deny credentials completed: matchRule=${matchRule}, shouldDeny=${shouldDeny}` + ) return { shouldAllow: false, shouldDeny } } else { // listType === 'allow' @@ -148,6 +168,9 @@ async function evaluateCredentialList( // ALL rules must match shouldAllow = matchResults.every((r) => r === true) } + CORE_LOGGER.info( + `Allow credentials completed: matchRule=${matchRule}, shouldAllow=${shouldAllow}` + ) return { shouldAllow, shouldDeny: false } } } @@ -185,14 +208,33 @@ export async function checkSingleCredential( return false } - const normalizedValues = addressCredential.values - .filter((value: unknown): value is string => typeof value === 'string') - .map((value: string) => value.toLowerCase()) + const normalizedValues = addressCredential.values.flatMap( + (value: unknown): string[] => { + if (typeof value === 'string') return [value.toLowerCase()] + if ( + value && + typeof value === 'object' && + 'address' in value && + typeof value.address === 'string' + ) { + return [value.address.toLowerCase()] + } + return [] + } + ) if (normalizedValues.length !== addressCredential.values.length) { - CORE_LOGGER.warn('Address credential contains non-string values; ignoring them') + CORE_LOGGER.warn( + 'Address credential contains unsupported values; ignoring invalid entries' + ) } + CORE_LOGGER.info( + `Address credential normalized: inputCount=${addressCredential.values.length}, validCount=${normalizedValues.length}, hasWildcard=${normalizedValues.includes( + '*' + )}` + ) + // Check for wildcard (*) if (normalizedValues.includes('*')) { return true From 4ad8d82688eddbe53ef8f74dc22953f00d017d7c Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Wed, 12 Aug 2026 14:14:10 +0300 Subject: [PATCH 08/17] fix: remove logs --- src/utils/credentials.ts | 42 +--------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index 84ad25b50..871a109cd 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -32,7 +32,6 @@ export async function checkCredentials( signer: Signer ): Promise { // If credentials are undefined or empty, allow access - CORE_LOGGER.info(`Checking credentials for consumer address: ${consumerAddress}`) if (!isDefined(credentials)) { return true } @@ -53,8 +52,6 @@ export async function checkCredentials( matchDeny, 'deny' ) - CORE_LOGGER.info(`Deny evaluation result: ${JSON.stringify(denyResult)}`) - // If evaluation says to deny, return false if (denyResult.shouldDeny) { CORE_LOGGER.logMessage( @@ -67,11 +64,7 @@ export async function checkCredentials( // ======================================== // STEP 2: Check ALLOW list // ======================================== - CORE_LOGGER.info( - `isDefined(credentials.allow): ${isDefined(credentials.allow)}, credentials.allow.length: ${credentials.allow?.length ?? 0}` - ) if (isDefined(credentials.allow) && credentials.allow.length > 0) { - CORE_LOGGER.info(`Allow evaluation started for consumer address: ${consumerAddress}`) const allowResult = await evaluateCredentialList( credentials.allow, normalizedAddress, @@ -79,7 +72,6 @@ export async function checkCredentials( matchAllow, 'allow' ) - CORE_LOGGER.info(`Allow evaluation result: ${JSON.stringify(allowResult)}`) return allowResult.shouldAllow } @@ -98,20 +90,8 @@ async function evaluateCredentialList( listType: 'allow' | 'deny' ): Promise<{ shouldAllow: boolean; shouldDeny: boolean }> { const matchResults: boolean[] = [] - CORE_LOGGER.info( - `Evaluating ${listType} credential list: count=${credentialList.length}, matchRule=${matchRule}` - ) - - for (const [index, credential] of credentialList.entries()) { - CORE_LOGGER.info( - `Evaluating ${listType} credential at index ${index}: type=${String( - credential?.type - )}` - ) + for (const credential of credentialList) { const matchResult = await checkSingleCredential(credential, consumerAddress, signer) - CORE_LOGGER.info( - `${listType} credential at index ${index} matched: ${String(matchResult)}` - ) if (matchResult === null) { // Unknown or unsupported credential type @@ -132,7 +112,6 @@ async function evaluateCredentialList( // No valid credential checks were performed if (matchResults.length === 0) { - CORE_LOGGER.info(`No valid results produced for ${listType} credentials`) if (listType === 'allow') { // No valid allow rules means deny return { shouldAllow: false, shouldDeny: false } @@ -153,9 +132,6 @@ async function evaluateCredentialList( // If ALL rules match, deny shouldDeny = matchResults.every((r) => r === true) } - CORE_LOGGER.info( - `Deny credentials completed: matchRule=${matchRule}, shouldDeny=${shouldDeny}` - ) return { shouldAllow: false, shouldDeny } } else { // listType === 'allow' @@ -168,9 +144,6 @@ async function evaluateCredentialList( // ALL rules must match shouldAllow = matchResults.every((r) => r === true) } - CORE_LOGGER.info( - `Allow credentials completed: matchRule=${matchRule}, shouldAllow=${shouldAllow}` - ) return { shouldAllow, shouldDeny: false } } } @@ -189,7 +162,6 @@ export async function checkSingleCredential( signer: Signer | null ): Promise { if (!credential || typeof credential.type !== 'string') { - CORE_LOGGER.warn('Credential is missing a valid string type') return null } const credentialType = credential.type.toLowerCase() @@ -223,18 +195,6 @@ export async function checkSingleCredential( } ) - if (normalizedValues.length !== addressCredential.values.length) { - CORE_LOGGER.warn( - 'Address credential contains unsupported values; ignoring invalid entries' - ) - } - - CORE_LOGGER.info( - `Address credential normalized: inputCount=${addressCredential.values.length}, validCount=${normalizedValues.length}, hasWildcard=${normalizedValues.includes( - '*' - )}` - ) - // Check for wildcard (*) if (normalizedValues.includes('*')) { return true From b6a2086c3e8a6b882d3932aeff10f9c5c5376b33 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 08:38:37 +0300 Subject: [PATCH 09/17] fix: tests --- src/test/integration/credentials.test.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/test/integration/credentials.test.ts b/src/test/integration/credentials.test.ts index b2e2fed48..e150cf183 100644 --- a/src/test/integration/credentials.test.ts +++ b/src/test/integration/credentials.test.ts @@ -31,6 +31,7 @@ import { } from '../../utils/index.js' import { DownloadHandler } from '../../components/core/handler/downloadHandler.js' import { GetDdoHandler } from '../../components/core/handler/ddoHandler.js' +import { ProviderFees } from '../../components/core/utils/feesHandler.js' import { Readable } from 'stream' import { OceanNodeConfig } from '../../@types/OceanNode.js' @@ -306,6 +307,21 @@ describe('********** [Credentials Flow] - Should run a complete node flo it('should start an order for all consumers', async function () { this.timeout(DEFAULT_TEST_TIMEOUT * 3) + const providerFeesFactory = new ProviderFees(oceanNode) + const createTestProviderFees = async (asset: any) => { + const service = asset.services[0] + const now = Date.now() / 1000 + const validUntil = service.timeout === 0 ? 0 : now + service.timeout + const providerFees = await providerFeesFactory.createProviderFee( + asset, + service, + validUntil + ) + assert(providerFees, 'provider fees could not be created') + return providerFees + } + + const providerFees = await createTestProviderFees(ddo) for (let i = 0; i < 3; i++) { const orderTxReceipt = await orderAsset( ddo, @@ -313,13 +329,16 @@ describe('********** [Credentials Flow] - Should run a complete node flo consumerAccounts[i], consumerAddresses[i], publisherAccount, - oceanNode + oceanNode, + providerFees ) assert(orderTxReceipt, `order transaction for consumer ${i} failed`) const txHash = orderTxReceipt.hash assert(txHash, `transaction id not found for consumer ${i}`) orderTxIds.push(txHash) } + + const providerFeesWithMatchAll = await createTestProviderFees(ddoWithMatchAll) for (let i = 0; i < 3; i++) { const orderTxReceipt = await orderAsset( ddoWithMatchAll, @@ -327,7 +346,8 @@ describe('********** [Credentials Flow] - Should run a complete node flo consumerAccounts[i], consumerAddresses[i], publisherAccount, - oceanNode + oceanNode, + providerFeesWithMatchAll ) assert(orderTxReceipt, `order transaction for consumer ${i} failed`) const txHash = orderTxReceipt.hash From 1fb94e7e70c4afaf34cd0b4ca3b22c8144fd9cdf Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 09:12:57 +0300 Subject: [PATCH 10/17] fix: add logs --- src/components/core/handler/downloadHandler.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/core/handler/downloadHandler.ts b/src/components/core/handler/downloadHandler.ts index 4c97b6b1b..009a7261f 100644 --- a/src/components/core/handler/downloadHandler.ts +++ b/src/components/core/handler/downloadHandler.ts @@ -313,6 +313,11 @@ export class DownloadHandler extends CommandHandler { if (credentials) { // if POLICY_SERVER_URL exists, then ocean-node will NOT perform any checks. // It will just use the existing code and let PolicyServer decide. + CORE_LOGGER.logMessage('Checking DDO level credentials', true) + CORE_LOGGER.logMessage( + 'isPolicyServerConfigured: ' + isPolicyServerConfigured(), + true + ) if (isPolicyServerConfigured()) { const response = await policyServer.checkDownload( ddoInstance.getDid(), @@ -321,14 +326,24 @@ export class DownloadHandler extends CommandHandler { task.consumerAddress, task.policyServer ) + CORE_LOGGER.logMessage( + 'Policy server response: ' + JSON.stringify(response), + true + ) accessGrantedDDOLevel = response.success } else { + CORE_LOGGER.logMessage('Checking DDO level credentials INTERNAL', true) + CORE_LOGGER.logMessage( + 'isPolicyServerConfigured: ' + isPolicyServerConfigured(), + true + ) accessGrantedDDOLevel = await checkCredentials( task.consumerAddress, credentials as Credentials, await blockchain.getSigner() ) } + CORE_LOGGER.logMessage('DDO level credentials check complete', true) if (!accessGrantedDDOLevel) { CORE_LOGGER.logMessage( `Error: Access to asset ${ddoInstance.getDid()} was denied`, From f967d48aeb7cf7773f1a78df4500d86abc3a0939 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 09:34:28 +0300 Subject: [PATCH 11/17] fix: logs --- src/components/core/handler/feesHandler.ts | 10 +++++++++- src/utils/credentials.ts | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/core/handler/feesHandler.ts b/src/components/core/handler/feesHandler.ts index 7d719c5a7..015134411 100644 --- a/src/components/core/handler/feesHandler.ts +++ b/src/components/core/handler/feesHandler.ts @@ -161,7 +161,7 @@ export class FeesHandler extends CommandHandler { accessGrantedDDOLevel = response.success } else { PROVIDER_LOGGER.info( - `Checking credentials for consumer address: ${task.consumerAddress}` + `Checking credentials for consumer address internal: ${task.consumerAddress}` ) accessGrantedDDOLevel = await checkCredentials( task.consumerAddress, @@ -195,12 +195,20 @@ export class FeesHandler extends CommandHandler { ) accessGrantedServiceLevel = accessGrantedDDOLevel || response.success } else { + PROVIDER_LOGGER.info( + 'Checking credentials for consumer address internal for service: ' + + task.consumerAddress + ) accessGrantedServiceLevel = await checkCredentials( task.consumerAddress, service.credentials, signer ) } + PROVIDER_LOGGER.info( + `service.credentials: ${JSON.stringify(service.credentials)}` + ) + PROVIDER_LOGGER.info(`accessGrantedServiceLevel: ${accessGrantedServiceLevel}`) if (!accessGrantedServiceLevel) { const error = `Error: Access to service with id ${service.id} was denied` diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index 871a109cd..be731c4f5 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -65,6 +65,16 @@ export async function checkCredentials( // STEP 2: Check ALLOW list // ======================================== if (isDefined(credentials.allow) && credentials.allow.length > 0) { + CORE_LOGGER.logMessage( + `Checking ALLOW list with params: ${JSON.stringify({ + credentialList: credentials.allow, + consumerAddress: normalizedAddress, + signerPresent: Boolean(signer), + matchRule: matchAllow, + listType: 'allow' + })}`, + true + ) const allowResult = await evaluateCredentialList( credentials.allow, normalizedAddress, @@ -72,6 +82,8 @@ export async function checkCredentials( matchAllow, 'allow' ) + CORE_LOGGER.logMessage('Checking ALLOW list credentials', true) + CORE_LOGGER.logMessage('ALLOW list result: ' + JSON.stringify(allowResult), true) return allowResult.shouldAllow } From e676d078637b30bf668ee87cdf79a7bc9ac12196 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 10:04:18 +0300 Subject: [PATCH 12/17] fix: logs --- .../Indexer/processors/BaseProcessor.ts | 29 +++++++++++++++++-- src/components/core/handler/ddoHandler.ts | 14 +++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/components/Indexer/processors/BaseProcessor.ts b/src/components/Indexer/processors/BaseProcessor.ts index 939260be0..2033838a1 100644 --- a/src/components/Indexer/processors/BaseProcessor.ts +++ b/src/components/Indexer/processors/BaseProcessor.ts @@ -271,10 +271,13 @@ export abstract class BaseEventProcessor { } else { return Date.now().toString() } - } catch (err) { + } catch (err: any) { + const responseDetails = err.response + ? `status=${err.response.status}, statusText=${err.response.statusText}, body=${JSON.stringify(err.response.data)}` + : `code=${err.code ?? 'unknown'}, message=${err.message}` INDEXER_LOGGER.log( LOG_LEVELS_STR.LEVEL_ERROR, - `decryptDDO: Error getting nonce, using timestamp: ${err.message}` + `decryptDDO: Error getting nonce from ${decryptorURL} for decrypterAddress=${address}; ${responseDetails}. Using timestamp fallback.` ) return Date.now().toString() } @@ -328,6 +331,21 @@ export abstract class BaseEventProcessor { signature, nonce } + INDEXER_LOGGER.log( + LOG_LEVELS_STR.LEVEL_INFO, + `decryptDDO: Sending decrypt request: ${JSON.stringify({ + url: `${decryptorURL}/api/services/decrypt`, + transactionId: txId || null, + chainId, + decrypterAddress: ethAddress, + dataNftAddress: contractAddress, + flags: parseInt(flag), + documentHash: metadataHash || null, + nonce, + hasEncryptedDocument: Boolean(payload.encryptedDocument), + hasSignature: Boolean(signature) + })}` + ) try { const res = await axios({ method: 'post', @@ -375,6 +393,13 @@ export abstract class BaseEventProcessor { throw err } + const responseDetails = err.response + ? `status=${err.response.status}, statusText=${err.response.statusText}, body=${JSON.stringify(err.response.data)}` + : `code=${err.code ?? 'unknown'}, message=${err.message}` + INDEXER_LOGGER.log( + LOG_LEVELS_STR.LEVEL_ERROR, + `decryptDDO: HTTP request failed for decryptorURL=${decryptorURL}, transactionId=${txId || 'none'}, chainId=${chainId}, decrypterAddress=${ethAddress}; ${responseDetails}` + ) throw err } }) diff --git a/src/components/core/handler/ddoHandler.ts b/src/components/core/handler/ddoHandler.ts index aa4f7f752..80054d749 100644 --- a/src/components/core/handler/ddoHandler.ts +++ b/src/components/core/handler/ddoHandler.ts @@ -136,6 +136,20 @@ export class DecryptDdoHandler extends CommandHandler { task.command ) if (isAuthRequestValid.status.httpStatus !== 200) { + CORE_LOGGER.error( + `Decrypt DDO authentication failed: ${JSON.stringify({ + decrypterAddress: task.decrypterAddress, + chainId: task.chainId, + transactionId: task.transactionId || null, + command: task.command, + nonce: task.nonce, + caller: task.caller || null, + hasAuthorization: Boolean(task.authorization), + hasSignature: Boolean(task.signature), + status: isAuthRequestValid.status.httpStatus, + error: isAuthRequestValid.status.error + })}` + ) return isAuthRequestValid } From c465ae4ad1be97d4267deec5f988e2b1a2d7890e Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 10:43:58 +0300 Subject: [PATCH 13/17] fix: add more logs --- src/components/core/utils/nonceHandler.ts | 95 +++++++++++++++++++++-- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/src/components/core/utils/nonceHandler.ts b/src/components/core/utils/nonceHandler.ts index 44ecdea5c..59b4771a1 100644 --- a/src/components/core/utils/nonceHandler.ts +++ b/src/components/core/utils/nonceHandler.ts @@ -189,7 +189,24 @@ async function validateNonceAndSignature( config: OceanNodeConfig, chainId?: string | null ): Promise { + CORE_LOGGER.logMessage( + `Validating nonce and signature: ${JSON.stringify({ + nonce, + existingNonce, + consumer, + command, + chainId: chainId || null, + signaturePresent: Boolean(signature), + signatureLength: signature?.length || 0, + signaturePrefix: signature?.slice(0, 10) || null + })}`, + true + ) + if (nonce <= existingNonce) { + CORE_LOGGER.error( + `Nonce validation failed: received nonce ${nonce} is not greater than existing nonce ${existingNonce} for consumer ${consumer}` + ) return { valid: false, error: 'nonce: ' + nonce + ' is not a valid nonce' @@ -201,46 +218,108 @@ async function validateNonceAndSignature( [ethers.hexlify(ethers.toUtf8Bytes(message))] ) const messageHashBytes = ethers.toBeArray(consumerMessage) + CORE_LOGGER.logMessage( + `Signature verification inputs: ${JSON.stringify({ + message, + consumerMessage, + messageHashBytesLength: messageHashBytes.length + })}`, + true + ) // Try EOA signature validation try { const addressFromHashSignature = ethers.verifyMessage(consumerMessage, signature) const addressFromBytesSignature = ethers.verifyMessage(messageHashBytes, signature) - if ( - ethers.getAddress(addressFromHashSignature)?.toLowerCase() === - ethers.getAddress(consumer)?.toLowerCase() || - ethers.getAddress(addressFromBytesSignature)?.toLowerCase() === - ethers.getAddress(consumer)?.toLowerCase() - ) { + const normalizedConsumer = ethers.getAddress(consumer).toLowerCase() + const hashSignatureMatches = + ethers.getAddress(addressFromHashSignature).toLowerCase() === normalizedConsumer + const bytesSignatureMatches = + ethers.getAddress(addressFromBytesSignature).toLowerCase() === normalizedConsumer + + CORE_LOGGER.logMessage( + `EOA signature verification result: ${JSON.stringify({ + normalizedConsumer, + addressFromHashSignature, + addressFromBytesSignature, + hashSignatureMatches, + bytesSignatureMatches + })}`, + true + ) + + if (hashSignatureMatches || bytesSignatureMatches) { return { valid: true } } } catch (error) { + CORE_LOGGER.error( + `EOA signature verification threw an error for consumer ${consumer}: ${error instanceof Error ? error.message : String(error)}` + ) // Continue to smart account check } // Try ERC-1271 (smart account) validation try { const targetChainId = chainId || Object.keys(config?.supportedNetworks || {})[0] + CORE_LOGGER.logMessage( + `Starting ERC-1271 signature verification: ${JSON.stringify({ + consumer, + targetChainId: targetChainId || null, + networkConfigured: Boolean( + targetChainId && config?.supportedNetworks?.[targetChainId] + ) + })}`, + true + ) if (targetChainId && config?.supportedNetworks?.[targetChainId]) { const provider = new ethers.JsonRpcProvider( config.supportedNetworks[targetChainId].rpc ) // Try custom hash format (for backward compatibility) - if (await isERC1271Valid(consumer, consumerMessage, signature, provider)) { + const customHashValid = await isERC1271Valid( + consumer, + consumerMessage, + signature, + provider + ) + CORE_LOGGER.logMessage( + `ERC-1271 custom hash verification result: ${customHashValid}`, + true + ) + if (customHashValid) { return { valid: true } } // Try EIP-191 prefixed hash (standard for smart wallets) const eip191Hash = ethers.hashMessage(message) - if (await isERC1271Valid(consumer, eip191Hash, signature, provider)) { + const eip191HashValid = await isERC1271Valid( + consumer, + eip191Hash, + signature, + provider + ) + CORE_LOGGER.logMessage( + `ERC-1271 EIP-191 hash verification result: ${JSON.stringify({ + eip191Hash, + valid: eip191HashValid + })}`, + true + ) + if (eip191HashValid) { return { valid: true } } } } catch (error) { + CORE_LOGGER.error( + `ERC-1271 signature verification threw an error for consumer ${consumer}: ${error instanceof Error ? error.message : String(error)}` + ) // Smart account validation failed } + CORE_LOGGER.error( + `All signature verification methods failed for consumer ${consumer}, nonce ${nonce}, command ${command}` + ) return { valid: false, error: 'consumer address and nonce signature mismatch' From 2cf782400134b212cca520ddbe5b91aecfea120d Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 10:53:54 +0300 Subject: [PATCH 14/17] fix: fix --- src/components/core/utils/nonceHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/core/utils/nonceHandler.ts b/src/components/core/utils/nonceHandler.ts index 59b4771a1..5872b8ccb 100644 --- a/src/components/core/utils/nonceHandler.ts +++ b/src/components/core/utils/nonceHandler.ts @@ -217,7 +217,7 @@ async function validateNonceAndSignature( ['bytes'], [ethers.hexlify(ethers.toUtf8Bytes(message))] ) - const messageHashBytes = ethers.toBeArray(consumerMessage) + const messageHashBytes = ethers.getBytes(consumerMessage) CORE_LOGGER.logMessage( `Signature verification inputs: ${JSON.stringify({ message, From bcc0c271ef5c1337f2a0dc5254a0eaa136bd7cc5 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 11:01:33 +0300 Subject: [PATCH 15/17] fix: removed logs --- .../Indexer/processors/BaseProcessor.ts | 29 +----- src/components/core/handler/ddoHandler.ts | 14 --- src/components/core/utils/nonceHandler.ts | 95 ++----------------- src/utils/credentials.ts | 12 --- 4 files changed, 10 insertions(+), 140 deletions(-) diff --git a/src/components/Indexer/processors/BaseProcessor.ts b/src/components/Indexer/processors/BaseProcessor.ts index 2033838a1..939260be0 100644 --- a/src/components/Indexer/processors/BaseProcessor.ts +++ b/src/components/Indexer/processors/BaseProcessor.ts @@ -271,13 +271,10 @@ export abstract class BaseEventProcessor { } else { return Date.now().toString() } - } catch (err: any) { - const responseDetails = err.response - ? `status=${err.response.status}, statusText=${err.response.statusText}, body=${JSON.stringify(err.response.data)}` - : `code=${err.code ?? 'unknown'}, message=${err.message}` + } catch (err) { INDEXER_LOGGER.log( LOG_LEVELS_STR.LEVEL_ERROR, - `decryptDDO: Error getting nonce from ${decryptorURL} for decrypterAddress=${address}; ${responseDetails}. Using timestamp fallback.` + `decryptDDO: Error getting nonce, using timestamp: ${err.message}` ) return Date.now().toString() } @@ -331,21 +328,6 @@ export abstract class BaseEventProcessor { signature, nonce } - INDEXER_LOGGER.log( - LOG_LEVELS_STR.LEVEL_INFO, - `decryptDDO: Sending decrypt request: ${JSON.stringify({ - url: `${decryptorURL}/api/services/decrypt`, - transactionId: txId || null, - chainId, - decrypterAddress: ethAddress, - dataNftAddress: contractAddress, - flags: parseInt(flag), - documentHash: metadataHash || null, - nonce, - hasEncryptedDocument: Boolean(payload.encryptedDocument), - hasSignature: Boolean(signature) - })}` - ) try { const res = await axios({ method: 'post', @@ -393,13 +375,6 @@ export abstract class BaseEventProcessor { throw err } - const responseDetails = err.response - ? `status=${err.response.status}, statusText=${err.response.statusText}, body=${JSON.stringify(err.response.data)}` - : `code=${err.code ?? 'unknown'}, message=${err.message}` - INDEXER_LOGGER.log( - LOG_LEVELS_STR.LEVEL_ERROR, - `decryptDDO: HTTP request failed for decryptorURL=${decryptorURL}, transactionId=${txId || 'none'}, chainId=${chainId}, decrypterAddress=${ethAddress}; ${responseDetails}` - ) throw err } }) diff --git a/src/components/core/handler/ddoHandler.ts b/src/components/core/handler/ddoHandler.ts index 80054d749..aa4f7f752 100644 --- a/src/components/core/handler/ddoHandler.ts +++ b/src/components/core/handler/ddoHandler.ts @@ -136,20 +136,6 @@ export class DecryptDdoHandler extends CommandHandler { task.command ) if (isAuthRequestValid.status.httpStatus !== 200) { - CORE_LOGGER.error( - `Decrypt DDO authentication failed: ${JSON.stringify({ - decrypterAddress: task.decrypterAddress, - chainId: task.chainId, - transactionId: task.transactionId || null, - command: task.command, - nonce: task.nonce, - caller: task.caller || null, - hasAuthorization: Boolean(task.authorization), - hasSignature: Boolean(task.signature), - status: isAuthRequestValid.status.httpStatus, - error: isAuthRequestValid.status.error - })}` - ) return isAuthRequestValid } diff --git a/src/components/core/utils/nonceHandler.ts b/src/components/core/utils/nonceHandler.ts index 5872b8ccb..ddff7ea49 100644 --- a/src/components/core/utils/nonceHandler.ts +++ b/src/components/core/utils/nonceHandler.ts @@ -189,24 +189,7 @@ async function validateNonceAndSignature( config: OceanNodeConfig, chainId?: string | null ): Promise { - CORE_LOGGER.logMessage( - `Validating nonce and signature: ${JSON.stringify({ - nonce, - existingNonce, - consumer, - command, - chainId: chainId || null, - signaturePresent: Boolean(signature), - signatureLength: signature?.length || 0, - signaturePrefix: signature?.slice(0, 10) || null - })}`, - true - ) - if (nonce <= existingNonce) { - CORE_LOGGER.error( - `Nonce validation failed: received nonce ${nonce} is not greater than existing nonce ${existingNonce} for consumer ${consumer}` - ) return { valid: false, error: 'nonce: ' + nonce + ' is not a valid nonce' @@ -218,108 +201,46 @@ async function validateNonceAndSignature( [ethers.hexlify(ethers.toUtf8Bytes(message))] ) const messageHashBytes = ethers.getBytes(consumerMessage) - CORE_LOGGER.logMessage( - `Signature verification inputs: ${JSON.stringify({ - message, - consumerMessage, - messageHashBytesLength: messageHashBytes.length - })}`, - true - ) // Try EOA signature validation try { const addressFromHashSignature = ethers.verifyMessage(consumerMessage, signature) const addressFromBytesSignature = ethers.verifyMessage(messageHashBytes, signature) - const normalizedConsumer = ethers.getAddress(consumer).toLowerCase() - const hashSignatureMatches = - ethers.getAddress(addressFromHashSignature).toLowerCase() === normalizedConsumer - const bytesSignatureMatches = - ethers.getAddress(addressFromBytesSignature).toLowerCase() === normalizedConsumer - - CORE_LOGGER.logMessage( - `EOA signature verification result: ${JSON.stringify({ - normalizedConsumer, - addressFromHashSignature, - addressFromBytesSignature, - hashSignatureMatches, - bytesSignatureMatches - })}`, - true - ) - - if (hashSignatureMatches || bytesSignatureMatches) { + if ( + ethers.getAddress(addressFromHashSignature)?.toLowerCase() === + ethers.getAddress(consumer)?.toLowerCase() || + ethers.getAddress(addressFromBytesSignature)?.toLowerCase() === + ethers.getAddress(consumer)?.toLowerCase() + ) { return { valid: true } } } catch (error) { - CORE_LOGGER.error( - `EOA signature verification threw an error for consumer ${consumer}: ${error instanceof Error ? error.message : String(error)}` - ) // Continue to smart account check } // Try ERC-1271 (smart account) validation try { const targetChainId = chainId || Object.keys(config?.supportedNetworks || {})[0] - CORE_LOGGER.logMessage( - `Starting ERC-1271 signature verification: ${JSON.stringify({ - consumer, - targetChainId: targetChainId || null, - networkConfigured: Boolean( - targetChainId && config?.supportedNetworks?.[targetChainId] - ) - })}`, - true - ) if (targetChainId && config?.supportedNetworks?.[targetChainId]) { const provider = new ethers.JsonRpcProvider( config.supportedNetworks[targetChainId].rpc ) // Try custom hash format (for backward compatibility) - const customHashValid = await isERC1271Valid( - consumer, - consumerMessage, - signature, - provider - ) - CORE_LOGGER.logMessage( - `ERC-1271 custom hash verification result: ${customHashValid}`, - true - ) - if (customHashValid) { + if (await isERC1271Valid(consumer, consumerMessage, signature, provider)) { return { valid: true } } // Try EIP-191 prefixed hash (standard for smart wallets) const eip191Hash = ethers.hashMessage(message) - const eip191HashValid = await isERC1271Valid( - consumer, - eip191Hash, - signature, - provider - ) - CORE_LOGGER.logMessage( - `ERC-1271 EIP-191 hash verification result: ${JSON.stringify({ - eip191Hash, - valid: eip191HashValid - })}`, - true - ) - if (eip191HashValid) { + if (await isERC1271Valid(consumer, eip191Hash, signature, provider)) { return { valid: true } } } } catch (error) { - CORE_LOGGER.error( - `ERC-1271 signature verification threw an error for consumer ${consumer}: ${error instanceof Error ? error.message : String(error)}` - ) // Smart account validation failed } - CORE_LOGGER.error( - `All signature verification methods failed for consumer ${consumer}, nonce ${nonce}, command ${command}` - ) return { valid: false, error: 'consumer address and nonce signature mismatch' diff --git a/src/utils/credentials.ts b/src/utils/credentials.ts index be731c4f5..871a109cd 100644 --- a/src/utils/credentials.ts +++ b/src/utils/credentials.ts @@ -65,16 +65,6 @@ export async function checkCredentials( // STEP 2: Check ALLOW list // ======================================== if (isDefined(credentials.allow) && credentials.allow.length > 0) { - CORE_LOGGER.logMessage( - `Checking ALLOW list with params: ${JSON.stringify({ - credentialList: credentials.allow, - consumerAddress: normalizedAddress, - signerPresent: Boolean(signer), - matchRule: matchAllow, - listType: 'allow' - })}`, - true - ) const allowResult = await evaluateCredentialList( credentials.allow, normalizedAddress, @@ -82,8 +72,6 @@ export async function checkCredentials( matchAllow, 'allow' ) - CORE_LOGGER.logMessage('Checking ALLOW list credentials', true) - CORE_LOGGER.logMessage('ALLOW list result: ' + JSON.stringify(allowResult), true) return allowResult.shouldAllow } From 768ba66143c2ef74c5136526cb93dc2d1ddc28d2 Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 12:16:18 +0300 Subject: [PATCH 16/17] fix: version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac8b1e806..9a48661d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ocean-node", - "version": "3.2.2", + "version": "3.2.21", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ocean-node", - "version": "3.2.2", + "version": "3.2.21", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index e47d63b1f..2f79e8a5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ocean-node", - "version": "3.2.2", + "version": "3.2.21", "description": "Ocean Node is used to run all core services in the Ocean stack", "author": "Ocean Protocol Foundation", "license": "Apache-2.0", From 75ccc1c0a36c87b90a451f370fd60f8067e290ba Mon Sep 17 00:00:00 2001 From: AdriGeorge Date: Thu, 13 Aug 2026 13:07:58 +0300 Subject: [PATCH 17/17] fix: add legacy --- src/components/core/utils/nonceHandler.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/core/utils/nonceHandler.ts b/src/components/core/utils/nonceHandler.ts index ddff7ea49..59884c498 100644 --- a/src/components/core/utils/nonceHandler.ts +++ b/src/components/core/utils/nonceHandler.ts @@ -201,15 +201,22 @@ async function validateNonceAndSignature( [ethers.hexlify(ethers.toUtf8Bytes(message))] ) const messageHashBytes = ethers.getBytes(consumerMessage) + const legacyMessageHashBytes = ethers.toBeArray(consumerMessage) // Try EOA signature validation try { const addressFromHashSignature = ethers.verifyMessage(consumerMessage, signature) const addressFromBytesSignature = ethers.verifyMessage(messageHashBytes, signature) + const addressFromLegacyBytesSignature = ethers.verifyMessage( + legacyMessageHashBytes, + signature + ) if ( ethers.getAddress(addressFromHashSignature)?.toLowerCase() === ethers.getAddress(consumer)?.toLowerCase() || ethers.getAddress(addressFromBytesSignature)?.toLowerCase() === + ethers.getAddress(consumer)?.toLowerCase() || + ethers.getAddress(addressFromLegacyBytesSignature)?.toLowerCase() === ethers.getAddress(consumer)?.toLowerCase() ) { return { valid: true }