diff --git a/.gitignore b/.gitignore
index 69dd198b0..cbe8657ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,5 @@ tsconfig.tsbuildinfo
__snapshots__
storybook-static
.qodo
-next-env.d.ts
\ No newline at end of file
+next-env.d.ts
+public/runtime-config.js
diff --git a/Dockerfile b/Dockerfile
index 905c28cf8..37960a092 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,7 +27,7 @@ ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
-COPY --from=builder /app/public ./public
+COPY --from=builder --chown=nextjs:nodejs /app/public ./public
RUN mkdir .next
RUN chown nextjs:nodejs .next
@@ -35,10 +35,14 @@ RUN chown nextjs:nodejs .next
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
+COPY --chown=nextjs:nodejs ./scripts/docker-entrypoint.sh /app/docker-entrypoint.sh
+RUN chmod +x /app/docker-entrypoint.sh
+
USER nextjs
EXPOSE 8008
ENV PORT=8008
ENV HOSTNAME="0.0.0.0"
+ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["node", "server.js"]
diff --git a/app.config.cjs b/app.config.cjs
index 327d96379..8d1e42560 100644
--- a/app.config.cjs
+++ b/app.config.cjs
@@ -1,3 +1,12 @@
+const getEnv = (key) => {
+ const hasWindow = typeof window !== 'undefined'
+ if (hasWindow && window.__RUNTIME_CONFIG__) {
+ const value = window.__RUNTIME_CONFIG__[key]
+ if (typeof value !== 'undefined') return value
+ }
+ return process.env[key]
+}
+
module.exports = {
// URI of single metadata cache instance for all networks.
// While ocean.js includes this value for each network as part of its ConfigHelper,
@@ -6,12 +15,14 @@ module.exports = {
// const { appConfig } = useMarketMetadata()
// return appConfig.metadataCacheUri
metadataCacheUri:
+ getEnv('NEXT_PUBLIC_METADATACACHE_URI') ||
process.env.NEXT_PUBLIC_METADATACACHE_URI ||
'https://ocean-node-vm3.oceanenterprise.io',
nodeUri:
+ getEnv('NEXT_PUBLIC_NODE_URI') ||
process.env.NEXT_PUBLIC_NODE_URI ||
- 'https://eth-sepolia.blastapi.io/a91cc615-dbae-493b-b011-5796477a64de',
+ 'https://eth-sepolia-testnet.api.pocket.network',
// List of chainIds which metadata cache queries will return by default.
// This preselects the Chains user preferences.
@@ -20,31 +31,47 @@ module.exports = {
// List of all supported chainIds. Used to populate the Chains user preferences list.
chainIdsSupported: [1, 10, 11155111, 11155420],
- customProviderUrl: process.env.NEXT_PUBLIC_PROVIDER_URL,
+ customProviderUrl:
+ getEnv('NEXT_PUBLIC_PROVIDER_URL') || process.env.NEXT_PUBLIC_PROVIDER_URL,
defaultDatatokenCap:
'115792089237316195423570985008687907853269984665640564039457',
defaultDatatokenTemplateIndex: 2,
// The ETH address the marketplace fee will be sent to.
marketFeeAddress:
+ getEnv('NEXT_PUBLIC_MARKET_FEE_ADDRESS') ||
process.env.NEXT_PUBLIC_MARKET_FEE_ADDRESS ||
- '0x9984b2453eC7D99a73A5B3a46Da81f197B753C8d',
+ '0x43eB6644720CFD8B176DC971C6e8c17331812c04',
// publisher market fee that is taken upon ordering an asset, it is an absolute value, it is declared on erc20 creation
publisherMarketOrderFee:
- process.env.NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE || '0',
+ getEnv('NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE') ||
+ process.env.NEXT_PUBLIC_PUBLISHER_MARKET_ORDER_FEE ||
+ '0',
// fee recieved by the publisher market when a dt is bought from a fixed rate exchange, percent
publisherMarketFixedSwapFee:
- process.env.NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE || '0',
+ getEnv('NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE') ||
+ process.env.NEXT_PUBLIC_PUBLISHER_MARKET_FIXED_SWAP_FEE ||
+ '0',
// consume market fee that is taken upon ordering an asset, it is an absolute value with 18 decimals, it is specified on order
consumeMarketOrderFee:
- process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE || '0',
- consumeMarketFee: process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE || '0',
+ getEnv('NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE') ||
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE ||
+ '0',
+ consumeMarketFee:
+ getEnv('NEXT_PUBLIC_CONSUME_MARKET_FEE') ||
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE ||
+ '0',
// fee recieved by the consume market when a dt is bought from a fixed rate exchange, percent
consumeMarketFixedSwapFee:
- process.env.NEXT_PUBLIC_CONSUME_MARKET_FIXED_SWAP_FEE || '0',
+ getEnv('NEXT_PUBLIC_CONSUME_MARKET_FIXED_SWAP_FEE') ||
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_FIXED_SWAP_FEE ||
+ '0',
- marketCommunityFee: process.env.NEXT_PUBLIC_MARKET_COMMUNITY_FEE || '0.3',
+ marketCommunityFee:
+ getEnv('NEXT_PUBLIC_MARKET_COMMUNITY_FEE') ||
+ process.env.NEXT_PUBLIC_MARKET_COMMUNITY_FEE ||
+ '0',
// Config for https://github.com/oceanprotocol/use-dark-mode
darkModeConfig: {
@@ -55,9 +82,18 @@ module.exports = {
// Used to show or hide the fixed, dynamic or free price options
// tab to publishers during the price creation.
- allowFixedPricing: process.env.NEXT_PUBLIC_ALLOW_FIXED_PRICING || 'true',
- allowDynamicPricing: process.env.NEXT_PUBLIC_ALLOW_DYNAMIC_PRICING || 'false',
- allowFreePricing: process.env.NEXT_PUBLIC_ALLOW_FREE_PRICING || 'true',
+ allowFixedPricing:
+ getEnv('NEXT_PUBLIC_ALLOW_FIXED_PRICING') ||
+ process.env.NEXT_PUBLIC_ALLOW_FIXED_PRICING ||
+ 'true',
+ allowDynamicPricing:
+ getEnv('NEXT_PUBLIC_ALLOW_DYNAMIC_PRICING') ||
+ process.env.NEXT_PUBLIC_ALLOW_DYNAMIC_PRICING ||
+ 'false',
+ allowFreePricing:
+ getEnv('NEXT_PUBLIC_ALLOW_FREE_PRICING') ||
+ process.env.NEXT_PUBLIC_ALLOW_FREE_PRICING ||
+ 'true',
// Set the default privacy policy to initially display
// this should be the slug of your default policy markdown file
@@ -69,50 +105,79 @@ module.exports = {
// is used to create and show a privacy preference center / cookie banner
// To learn more about how to configure and use this, please refer to the readme
privacyPreferenceCenter:
- process.env.NEXT_PUBLIC_PRIVACY_PREFERENCE_CENTER || 'true',
+ getEnv('NEXT_PUBLIC_PRIVACY_PREFERENCE_CENTER') ||
+ process.env.NEXT_PUBLIC_PRIVACY_PREFERENCE_CENTER ||
+ 'true',
// Default terms to be used for service offerings made on this marketplace
defaultAccessTerms:
'https://raw.githubusercontent.com/OceanProtocolEnterprise/market/main/content/pages/terms.md',
// Purgatory URI, leave as an empty string to disable the API call
- purgatoryUrl: process.env.NEXT_PUBLIC_PURGATORY_URI || '',
+ purgatoryUrl:
+ getEnv('NEXT_PUBLIC_PURGATORY_URI') ||
+ process.env.NEXT_PUBLIC_PURGATORY_URI ||
+ '',
// The url used to fetch docker hub image info
dockerHubProxyUrl:
+ getEnv('NEXT_PUBLIC_DOCKER_HUB_PROXY_URL') ||
process.env.NEXT_PUBLIC_DOCKER_HUB_PROXY_URL ||
'https://dockerhub-proxy.oceanprotocol.com',
// Display alert banner for the developer preview deployment
- showPreviewAlert: process.env.NEXT_PUBLIC_SHOW_PREVIEW_ALERT || 'false',
+ showPreviewAlert:
+ getEnv('NEXT_PUBLIC_SHOW_PREVIEW_ALERT') ||
+ process.env.NEXT_PUBLIC_SHOW_PREVIEW_ALERT ||
+ 'false',
- encryptAsset: process.env.NEXT_PUBLIC_ENCRYPT_ASSET
- ? process.env.NEXT_PUBLIC_ENCRYPT_ASSET === 'true'
- : false,
+ encryptAsset:
+ getEnv('NEXT_PUBLIC_ENCRYPT_ASSET') || process.env.NEXT_PUBLIC_ENCRYPT_ASSET
+ ? (getEnv('NEXT_PUBLIC_ENCRYPT_ASSET') ||
+ process.env.NEXT_PUBLIC_ENCRYPT_ASSET) === 'true'
+ : false,
// This enables / disables the ssi support
- ssiEnabled: process.env.NEXT_PUBLIC_SSI_ENABLED
- ? process.env.NEXT_PUBLIC_SSI_ENABLED === 'true'
- : false,
+ ssiEnabled:
+ getEnv('NEXT_PUBLIC_SSI_ENABLED') || process.env.NEXT_PUBLIC_SSI_ENABLED
+ ? (getEnv('NEXT_PUBLIC_SSI_ENABLED') ||
+ process.env.NEXT_PUBLIC_SSI_ENABLED) === 'true'
+ : false,
ssiWalletApi:
- process.env.NEXT_PUBLIC_SSI_WALLET_API || 'https://wallet.demo.walt.id',
+ getEnv('NEXT_PUBLIC_SSI_WALLET_API') ||
+ process.env.NEXT_PUBLIC_SSI_WALLET_API ||
+ 'https://wallet.demo.oceanenterprise.io',
ssiDefaultPolicyUrl:
+ getEnv('NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL') ||
process.env.NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL ||
'https://raw.githubusercontent.com/OceanProtocolEnterprise/policy-server/refs/heads/main/default-verification-policies',
- ipfsJWT: process.env.NEXT_PUBLIC_IPFS_JWT,
- ipfsGateway: process.env.NEXT_PUBLIC_IPFS_GATEWAY,
- ipfsUnpinFiles: process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES
- ? process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES === 'true'
- : false,
-
- opaServer: process.env.NEXT_PUBLIC_OPA_SERVER_URL,
+ ipfsJWT: getEnv('NEXT_PUBLIC_IPFS_JWT') || process.env.NEXT_PUBLIC_IPFS_JWT,
+ ipfsGateway:
+ getEnv('NEXT_PUBLIC_IPFS_GATEWAY') || process.env.NEXT_PUBLIC_IPFS_GATEWAY,
+ ipfsUnpinFiles:
+ getEnv('NEXT_PUBLIC_IPFS_UNPIN_FILES') ||
+ process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES
+ ? (getEnv('NEXT_PUBLIC_IPFS_UNPIN_FILES') ||
+ process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES) === 'true'
+ : false,
+
+ opaServer:
+ getEnv('NEXT_PUBLIC_OPA_SERVER_URL') ||
+ process.env.NEXT_PUBLIC_OPA_SERVER_URL,
showOnboardingModuleByDefault:
- process.env.NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT === 'false',
- nodeUriIndex: process.env.NEXT_PUBLIC_NODE_URI_INDEXED
- ? JSON.parse(process.env.NEXT_PUBLIC_NODE_URI_INDEXED)
- : [
- process.env.NEXT_PUBLIC_PROVIDER_URL ||
- 'https://ocean-node-vm3.oceanenterprise.io'
- ]
+ (getEnv('NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT') ||
+ process.env.NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT) === 'false',
+ nodeUriIndex:
+ getEnv('NEXT_PUBLIC_NODE_URI_INDEXED') ||
+ process.env.NEXT_PUBLIC_NODE_URI_INDEXED
+ ? JSON.parse(
+ getEnv('NEXT_PUBLIC_NODE_URI_INDEXED') ||
+ process.env.NEXT_PUBLIC_NODE_URI_INDEXED
+ )
+ : [
+ getEnv('NEXT_PUBLIC_PROVIDER_URL') ||
+ process.env.NEXT_PUBLIC_PROVIDER_URL ||
+ 'https://ocean-node-vm3.oceanenterprise.io'
+ ]
}
diff --git a/docker-compose.yml b/docker-compose.yml
index d12304339..698c44aaa 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,35 +1,12 @@
version: '3.8'
services:
ocean-market:
- build:
- context: .
- dockerfile: Dockerfile
- args:
- NEXT_PUBLIC_ENCRYPT_ASSET: ${NEXT_PUBLIC_ENCRYPT_ASSET}
- NEXT_PUBLIC_SSI_WALLET_API: ${NEXT_PUBLIC_SSI_WALLET_API}
- NEXT_PUBLIC_METADATACACHE_URI: ${NEXT_PUBLIC_METADATACACHE_URI}
- NEXT_PUBLIC_PROVIDER_URL: ${NEXT_PUBLIC_PROVIDER_URL}
- NEXT_PUBLIC_IPFS_UNPIN_FILES: ${NEXT_PUBLIC_IPFS_UNPIN_FILES}
- NEXT_PUBLIC_NODE_URI: ${NEXT_PUBLIC_NODE_URI}
- NEXT_PUBLIC_IPFS_GATEWAY: ${NEXT_PUBLIC_IPFS_GATEWAY}
- NEXT_PUBLIC_IPFS_JWT: ${NEXT_PUBLIC_IPFS_JWT}
- NEXT_PUBLIC_SSI_POLICY_SERVER: ${NEXT_PUBLIC_SSI_POLICY_SERVER}
- NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL: ${NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL}
- NEXT_PUBLIC_OPA_SERVER_URL: ${NEXT_PUBLIC_OPA_SERVER_URL}
- NEXT_PUBLIC_SSI_ENABLED: ${NEXT_PUBLIC_SSI_ENABLED}
- NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT: ${NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT}
- NEXT_PUBLIC_NODE_URI_INDEXED: ${NEXT_PUBLIC_NODE_URI_INDEXED}
- NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: ${NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID}
- NEXT_PUBLIC_INFURA_PROJECT_ID: ${NEXT_PUBLIC_INFURA_PROJECT_ID}
- NEXT_PUBLIC_CONSUME_MARKET_FEE: ${NEXT_PUBLIC_CONSUME_MARKET_FEE}
- NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE: ${NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE}
- NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION: ${NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION}
- NEXT_PUBLIC_NODE_URI_MAP: ${NEXT_PUBLIC_NODE_URI_MAP}
- NEXT_PUBLIC_MARKET_FEE_ADDRESS: ${NEXT_PUBLIC_MARKET_FEE_ADDRESS}
- NEXT_PUBLIC_ERC20_ADDRESSES: ${NEXT_PUBLIC_ERC20_ADDRESSES}
+ image: oceanenterprise/market:latest
container_name: ocean-market
ports:
- '8008:8008'
+ env_file:
+ - .env
environment:
NODE_ENV: production
restart: unless-stopped
diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh
new file mode 100644
index 000000000..6c006ca95
--- /dev/null
+++ b/scripts/docker-entrypoint.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+set -eu
+
+node - <<'NODE'
+const fs = require('fs')
+
+const config = {
+ NEXT_PUBLIC_ENCRYPT_ASSET: process.env.NEXT_PUBLIC_ENCRYPT_ASSET,
+ NEXT_PUBLIC_SSI_WALLET_API: process.env.NEXT_PUBLIC_SSI_WALLET_API,
+ NEXT_PUBLIC_METADATACACHE_URI: process.env.NEXT_PUBLIC_METADATACACHE_URI,
+ NEXT_PUBLIC_PROVIDER_URL: process.env.NEXT_PUBLIC_PROVIDER_URL,
+ NEXT_PUBLIC_IPFS_UNPIN_FILES: process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES,
+ NEXT_PUBLIC_NODE_URI: process.env.NEXT_PUBLIC_NODE_URI,
+ NEXT_PUBLIC_IPFS_GATEWAY: process.env.NEXT_PUBLIC_IPFS_GATEWAY,
+ NEXT_PUBLIC_IPFS_JWT: process.env.NEXT_PUBLIC_IPFS_JWT,
+ NEXT_PUBLIC_SSI_POLICY_SERVER: process.env.NEXT_PUBLIC_SSI_POLICY_SERVER,
+ NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL:
+ process.env.NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL,
+ NEXT_PUBLIC_OPA_SERVER_URL: process.env.NEXT_PUBLIC_OPA_SERVER_URL,
+ NEXT_PUBLIC_SSI_ENABLED: process.env.NEXT_PUBLIC_SSI_ENABLED,
+ NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT:
+ process.env.NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT,
+ NEXT_PUBLIC_NODE_URI_INDEXED: process.env.NEXT_PUBLIC_NODE_URI_INDEXED,
+ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID:
+ process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID,
+ NEXT_PUBLIC_INFURA_PROJECT_ID: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID,
+ NEXT_PUBLIC_CONSUME_MARKET_FEE: process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE,
+ NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE:
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE,
+ NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS:
+ process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
+ NEXT_PUBLIC_DISPENSER_ADDRESS: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
+ NEXT_PUBLIC_NFT_FACTORY_ADDRESS: process.env.NEXT_PUBLIC_NFT_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS,
+ NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION:
+ process.env.NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION,
+ NEXT_PUBLIC_NODE_URI_MAP: process.env.NEXT_PUBLIC_NODE_URI_MAP,
+ NEXT_PUBLIC_MARKET_FEE_ADDRESS: process.env.NEXT_PUBLIC_MARKET_FEE_ADDRESS,
+ NEXT_PUBLIC_ERC20_ADDRESSES: process.env.NEXT_PUBLIC_ERC20_ADDRESSES
+}
+
+fs.writeFileSync(
+ '/app/public/runtime-config.js',
+ `window.__RUNTIME_CONFIG__ = ${JSON.stringify(config)};\n`
+)
+NODE
+
+exec "$@"
diff --git a/scripts/pregenerate.sh b/scripts/pregenerate.sh
index 66a81a0cf..a9a7cbaec 100755
--- a/scripts/pregenerate.sh
+++ b/scripts/pregenerate.sh
@@ -5,3 +5,6 @@ node ./scripts/write-repo-metadata.cjs > content/repo-metadata.json
# Fetch EVM networks metadata
node ./scripts/write-networks-metadata.cjs > content/networks-metadata.json
+
+# Write runtime config for local dev/start
+node ./scripts/write-runtime-config.cjs
diff --git a/scripts/write-runtime-config.cjs b/scripts/write-runtime-config.cjs
new file mode 100644
index 000000000..d1eb2936e
--- /dev/null
+++ b/scripts/write-runtime-config.cjs
@@ -0,0 +1,66 @@
+const fs = require('fs')
+const path = require('path')
+
+const envPath = path.join(process.cwd(), '.env')
+if (fs.existsSync(envPath)) {
+ const lines = fs.readFileSync(envPath, 'utf8').split(/\r?\n/)
+ for (const line of lines) {
+ const trimmed = line.trim()
+ if (!trimmed || trimmed.startsWith('#')) continue
+ const eqIndex = trimmed.indexOf('=')
+ if (eqIndex === -1) continue
+ const key = trimmed.slice(0, eqIndex).trim()
+ let value = trimmed.slice(eqIndex + 1).trim()
+ if (
+ (value.startsWith('"') && value.endsWith('"')) ||
+ (value.startsWith("'") && value.endsWith("'"))
+ ) {
+ value = value.slice(1, -1)
+ }
+ if (typeof process.env[key] === 'undefined') {
+ process.env[key] = value
+ }
+ }
+}
+
+const config = {
+ NEXT_PUBLIC_ENCRYPT_ASSET: process.env.NEXT_PUBLIC_ENCRYPT_ASSET,
+ NEXT_PUBLIC_SSI_WALLET_API: process.env.NEXT_PUBLIC_SSI_WALLET_API,
+ NEXT_PUBLIC_METADATACACHE_URI: process.env.NEXT_PUBLIC_METADATACACHE_URI,
+ NEXT_PUBLIC_PROVIDER_URL: process.env.NEXT_PUBLIC_PROVIDER_URL,
+ NEXT_PUBLIC_IPFS_UNPIN_FILES: process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES,
+ NEXT_PUBLIC_NODE_URI: process.env.NEXT_PUBLIC_NODE_URI,
+ NEXT_PUBLIC_IPFS_GATEWAY: process.env.NEXT_PUBLIC_IPFS_GATEWAY,
+ NEXT_PUBLIC_IPFS_JWT: process.env.NEXT_PUBLIC_IPFS_JWT,
+ NEXT_PUBLIC_SSI_POLICY_SERVER: process.env.NEXT_PUBLIC_SSI_POLICY_SERVER,
+ NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL:
+ process.env.NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL,
+ NEXT_PUBLIC_OPA_SERVER_URL: process.env.NEXT_PUBLIC_OPA_SERVER_URL,
+ NEXT_PUBLIC_SSI_ENABLED: process.env.NEXT_PUBLIC_SSI_ENABLED,
+ NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT:
+ process.env.NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT,
+ NEXT_PUBLIC_NODE_URI_INDEXED: process.env.NEXT_PUBLIC_NODE_URI_INDEXED,
+ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID:
+ process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID,
+ NEXT_PUBLIC_INFURA_PROJECT_ID: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID,
+ NEXT_PUBLIC_CONSUME_MARKET_FEE: process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE,
+ NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE:
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE,
+ NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS:
+ process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
+ NEXT_PUBLIC_DISPENSER_ADDRESS: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
+ NEXT_PUBLIC_NFT_FACTORY_ADDRESS: process.env.NEXT_PUBLIC_NFT_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS,
+ NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION:
+ process.env.NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION,
+ NEXT_PUBLIC_NODE_URI_MAP: process.env.NEXT_PUBLIC_NODE_URI_MAP,
+ NEXT_PUBLIC_MARKET_FEE_ADDRESS: process.env.NEXT_PUBLIC_MARKET_FEE_ADDRESS,
+ NEXT_PUBLIC_ERC20_ADDRESSES: process.env.NEXT_PUBLIC_ERC20_ADDRESSES
+}
+
+const outputPath = path.join(process.cwd(), 'public', 'runtime-config.js')
+const contents = `window.__RUNTIME_CONFIG__ = ${JSON.stringify(config)};\n`
+fs.writeFileSync(outputPath, contents)
diff --git a/src/@context/UrqlProvider.tsx b/src/@context/UrqlProvider.tsx
index fb977d0ba..85cff9546 100644
--- a/src/@context/UrqlProvider.tsx
+++ b/src/@context/UrqlProvider.tsx
@@ -50,9 +50,6 @@ export default function UrqlClientProvider({
const newClient = createUrqlClient(oceanConfig.nodeUri)
urqlClient = newClient
setClient(newClient)
- LoggerInstance.log(
- `[URQL] Client connected to ${oceanConfig.nodeUri} (chainId: ${chainId})`
- )
}, [chainId]) // re-run when chain changes
return client ? {children} : <>>
diff --git a/src/@utils/credentialExpiration.ts b/src/@utils/credentialExpiration.ts
index b479efbb8..80fb183b0 100644
--- a/src/@utils/credentialExpiration.ts
+++ b/src/@utils/credentialExpiration.ts
@@ -1,3 +1,5 @@
+import { getRuntimeConfig } from './runtimeConfig'
+
export interface CredentialStatus {
isValid: boolean
expiresAt?: number
@@ -5,8 +7,10 @@ export interface CredentialStatus {
needsRefresh: boolean
}
+const runtimeConfig = getRuntimeConfig()
const CREDENTIAL_VALIDITY_DURATION =
- Number(process.env.NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION) || 5 * 60 * 1000
+ Number(runtimeConfig.NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION) ||
+ 5 * 60 * 1000
export function createCredentialStatus(
isValid: boolean,
diff --git a/src/@utils/ipfs.ts b/src/@utils/ipfs.ts
index cdd397de9..3c5b3fd2a 100644
--- a/src/@utils/ipfs.ts
+++ b/src/@utils/ipfs.ts
@@ -2,6 +2,7 @@ import * as isIPFS from 'is-ipfs'
import { FileItem } from '@utils/fileItem'
import { RemoteSource } from '../@types/ddo/RemoteSource'
import axios from 'axios'
+import { getRuntimeConfig } from './runtimeConfig'
export interface IpfsRemoteDocument {
content: string
@@ -42,7 +43,6 @@ export async function serverSideUploadToIpfs(
}
)
- // Pinata API response structure is { IpfsHash, PinSize, ... }
return response.data.IpfsHash
} catch (error) {
throw new Error(`[serverSideUploadToIpfs] ${error.message}`)
@@ -51,8 +51,11 @@ export async function serverSideUploadToIpfs(
export async function uploadToIPFS(data: any): Promise {
try {
+ const runtimeConfig = getRuntimeConfig()
+ const ipfsJWT = runtimeConfig.NEXT_PUBLIC_IPFS_JWT
const res = await fetch('/api/ipfs', {
method: 'POST',
+ headers: ipfsJWT ? { 'x-ipfs-jwt': ipfsJWT } : undefined,
body: JSON.stringify(data)
})
@@ -94,8 +97,11 @@ export async function serverSideDeleteIpfsFile(
export async function deleteIpfsFile(ipfsHash: string) {
try {
+ const runtimeConfig = getRuntimeConfig()
+ const ipfsJWT = runtimeConfig.NEXT_PUBLIC_IPFS_JWT
const res = await fetch('/api/ipfs', {
method: 'DELETE',
+ headers: ipfsJWT ? { 'x-ipfs-jwt': ipfsJWT } : undefined,
body: ipfsHash
})
diff --git a/src/@utils/ocean/index.ts b/src/@utils/ocean/index.ts
index 5dbb41f5d..8311797ad 100644
--- a/src/@utils/ocean/index.ts
+++ b/src/@utils/ocean/index.ts
@@ -3,6 +3,7 @@ import {
Config,
getOceanArtifactsAddressesByChainId
} from '@oceanprotocol/lib'
+import { getRuntimeConfig } from '../runtimeConfig'
/**
This function takes a Config object as an input and returns a new sanitized Config object
@@ -12,31 +13,33 @@ import {
@returns {Config} A new Config object
*/
export function sanitizeDevelopmentConfig(config: Config): Config {
+ const runtimeConfig = getRuntimeConfig()
return {
nodeUri: config.nodeUri,
- oceanNodeUri: process.env.NEXT_PUBLIC_PROVIDER_URL || config.oceanNodeUri,
+ oceanNodeUri: runtimeConfig.NEXT_PUBLIC_PROVIDER_URL || config.oceanNodeUri,
fixedRateExchangeAddress:
- process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
- dispenserAddress: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
+ runtimeConfig.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
+ dispenserAddress: runtimeConfig.NEXT_PUBLIC_DISPENSER_ADDRESS,
oceanTokenAddress: config.oceanTokenAddress,
- nftFactoryAddress: process.env.NEXT_PUBLIC_NFT_FACTORY_ADDRESS,
- routerFactoryAddress: process.env.NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS,
+ nftFactoryAddress: runtimeConfig.NEXT_PUBLIC_NFT_FACTORY_ADDRESS,
+ routerFactoryAddress: runtimeConfig.NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS,
accessListFactory:
config.accessListFactory ||
- process.env.NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS
+ runtimeConfig.NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS
} as Config
}
export function getOceanConfig(network: string | number): any {
+ const runtimeConfig = getRuntimeConfig()
// Load the RPC map from .env
- const rpcMap: Record = process.env.NEXT_PUBLIC_NODE_URI_MAP
- ? JSON.parse(process.env.NEXT_PUBLIC_NODE_URI_MAP)
+ const rpcMap: Record = runtimeConfig.NEXT_PUBLIC_NODE_URI_MAP
+ ? JSON.parse(runtimeConfig.NEXT_PUBLIC_NODE_URI_MAP)
: {}
- const erc20Map: Record = process.env
- .NEXT_PUBLIC_ERC20_ADDRESSES
- ? JSON.parse(process.env.NEXT_PUBLIC_ERC20_ADDRESSES)
- : {}
+ const erc20Map: Record =
+ runtimeConfig.NEXT_PUBLIC_ERC20_ADDRESSES
+ ? JSON.parse(runtimeConfig.NEXT_PUBLIC_ERC20_ADDRESSES)
+ : {}
if (!network) {
console.warn('[getOceanConfig] No network provided yet.')
@@ -52,7 +55,7 @@ export function getOceanConfig(network: string | number): any {
network === 56 ||
network === 8996
? undefined
- : process.env.NEXT_PUBLIC_INFURA_PROJECT_ID
+ : runtimeConfig.NEXT_PUBLIC_INFURA_PROJECT_ID
) as any
if (network === 8996) {
config = { ...config, ...sanitizeDevelopmentConfig(config) }
diff --git a/src/@utils/runtimeConfig.ts b/src/@utils/runtimeConfig.ts
new file mode 100644
index 000000000..6a0418513
--- /dev/null
+++ b/src/@utils/runtimeConfig.ts
@@ -0,0 +1,88 @@
+export type RuntimeConfig = {
+ NEXT_PUBLIC_ENCRYPT_ASSET?: string
+ NEXT_PUBLIC_METADATACACHE_URI?: string
+ NEXT_PUBLIC_SSI_WALLET_API?: string
+ NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL?: string
+ NEXT_PUBLIC_SSI_POLICY_SERVER?: string
+ NEXT_PUBLIC_SSI_ENABLED?: string
+ NEXT_PUBLIC_PROVIDER_URL?: string
+ NEXT_PUBLIC_IPFS_UNPIN_FILES?: string
+ NEXT_PUBLIC_NODE_URI?: string
+ NEXT_PUBLIC_IPFS_GATEWAY?: string
+ NEXT_PUBLIC_IPFS_JWT?: string
+ NEXT_PUBLIC_OPA_SERVER_URL?: string
+ NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT?: string
+ NEXT_PUBLIC_NODE_URI_INDEXED?: string
+ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID?: string
+ NEXT_PUBLIC_INFURA_PROJECT_ID?: string
+ NEXT_PUBLIC_CONSUME_MARKET_FEE?: string
+ NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE?: string
+ NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS?: string
+ NEXT_PUBLIC_DISPENSER_ADDRESS?: string
+ NEXT_PUBLIC_NFT_FACTORY_ADDRESS?: string
+ NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS?: string
+ NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS?: string
+ NEXT_PUBLIC_NODE_URI_MAP?: string
+ NEXT_PUBLIC_ERC20_ADDRESSES?: string
+ NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION?: string
+ NEXT_PUBLIC_MARKET_FEE_ADDRESS?: string
+ NEXT_PUBLIC_MARKET_DEVELOPMENT?: string
+}
+
+declare global {
+ interface Window {
+ __RUNTIME_CONFIG__?: RuntimeConfig
+ }
+}
+
+const runtimeConfig: RuntimeConfig = (() => {
+ const baseConfig: RuntimeConfig = {
+ NEXT_PUBLIC_ENCRYPT_ASSET: process.env.NEXT_PUBLIC_ENCRYPT_ASSET,
+ NEXT_PUBLIC_METADATACACHE_URI: process.env.NEXT_PUBLIC_METADATACACHE_URI,
+ NEXT_PUBLIC_SSI_WALLET_API: process.env.NEXT_PUBLIC_SSI_WALLET_API,
+ NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL:
+ process.env.NEXT_PUBLIC_SSI_DEFAULT_POLICIES_URL,
+ NEXT_PUBLIC_SSI_POLICY_SERVER: process.env.NEXT_PUBLIC_SSI_POLICY_SERVER,
+ NEXT_PUBLIC_SSI_ENABLED: process.env.NEXT_PUBLIC_SSI_ENABLED,
+ NEXT_PUBLIC_PROVIDER_URL: process.env.NEXT_PUBLIC_PROVIDER_URL,
+ NEXT_PUBLIC_IPFS_UNPIN_FILES: process.env.NEXT_PUBLIC_IPFS_UNPIN_FILES,
+ NEXT_PUBLIC_NODE_URI: process.env.NEXT_PUBLIC_NODE_URI,
+ NEXT_PUBLIC_IPFS_GATEWAY: process.env.NEXT_PUBLIC_IPFS_GATEWAY,
+ NEXT_PUBLIC_IPFS_JWT: process.env.NEXT_PUBLIC_IPFS_JWT,
+ NEXT_PUBLIC_OPA_SERVER_URL: process.env.NEXT_PUBLIC_OPA_SERVER_URL,
+ NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT:
+ process.env.NEXT_PUBLIC_SHOW_ONBOARDING_MODULE_BY_DEFAULT,
+ NEXT_PUBLIC_NODE_URI_INDEXED: process.env.NEXT_PUBLIC_NODE_URI_INDEXED,
+ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID:
+ process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID,
+ NEXT_PUBLIC_INFURA_PROJECT_ID: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID,
+ NEXT_PUBLIC_CONSUME_MARKET_FEE: process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE,
+ NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE:
+ process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE,
+ NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS:
+ process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
+ NEXT_PUBLIC_DISPENSER_ADDRESS: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
+ NEXT_PUBLIC_NFT_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_NFT_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ROUTER_FACTORY_ADDRESS,
+ NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS:
+ process.env.NEXT_PUBLIC_ACCESS_LIST_FACTORY_ADDRESS,
+ NEXT_PUBLIC_NODE_URI_MAP: process.env.NEXT_PUBLIC_NODE_URI_MAP,
+ NEXT_PUBLIC_ERC20_ADDRESSES: process.env.NEXT_PUBLIC_ERC20_ADDRESSES,
+ NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION:
+ process.env.NEXT_PUBLIC_CREDENTIAL_VALIDITY_DURATION,
+ NEXT_PUBLIC_MARKET_FEE_ADDRESS: process.env.NEXT_PUBLIC_MARKET_FEE_ADDRESS,
+ NEXT_PUBLIC_MARKET_DEVELOPMENT: process.env.NEXT_PUBLIC_MARKET_DEVELOPMENT
+ }
+
+ if (typeof window !== 'undefined' && window.__RUNTIME_CONFIG__) {
+ return { ...baseConfig, ...window.__RUNTIME_CONFIG__ }
+ }
+
+ return baseConfig
+})()
+
+export function getRuntimeConfig(): RuntimeConfig {
+ return runtimeConfig
+}
diff --git a/src/@utils/wallet/chains.ts b/src/@utils/wallet/chains.ts
index be198845f..135b83eda 100644
--- a/src/@utils/wallet/chains.ts
+++ b/src/@utils/wallet/chains.ts
@@ -1,5 +1,6 @@
import { Chain } from 'wagmi/chains'
import * as wagmiChains from 'wagmi/chains'
+import { getRuntimeConfig } from '../runtimeConfig'
// Custom OP Sepolia chain
export const opSepolia: Chain = {
@@ -48,8 +49,9 @@ export const getSupportedChains = (chainIdsSupported: number[]): Chain[] => {
const allChains = [...baseChains, opSepolia, ethereumHoodi]
// Load RPC map from .env
- const rpcMap: Record = process.env.NEXT_PUBLIC_NODE_URI_MAP
- ? JSON.parse(process.env.NEXT_PUBLIC_NODE_URI_MAP)
+ const runtimeConfig = getRuntimeConfig()
+ const rpcMap: Record = runtimeConfig.NEXT_PUBLIC_NODE_URI_MAP
+ ? JSON.parse(runtimeConfig.NEXT_PUBLIC_NODE_URI_MAP)
: {}
// Filter chains by allowed IDs and override RPCs if set in env
diff --git a/src/@utils/wallet/index.ts b/src/@utils/wallet/index.ts
index a917f3096..382bf7640 100644
--- a/src/@utils/wallet/index.ts
+++ b/src/@utils/wallet/index.ts
@@ -1,13 +1,12 @@
'use client'
import { LoggerInstance } from '@oceanprotocol/lib'
-import { cookieStorage, createConfig, createStorage, injected } from 'wagmi'
+import { cookieStorage, createConfig, createStorage } from 'wagmi'
import { erc20Abi, http } from 'viem'
import { localhost, type Chain } from 'wagmi/chains'
import {
ethers,
Contract,
- Signer,
formatEther,
JsonRpcProvider,
Provider,
@@ -17,7 +16,7 @@ import { getNetworkDisplayName } from '@hooks/useNetworkMetadata'
import { getOceanConfig } from '../ocean'
import { getSupportedChains } from './chains'
import { chainIdsSupported } from '../../../app.config.cjs'
-import { walletConnect } from 'wagmi/connectors'
+import { getRuntimeConfig } from '../runtimeConfig'
export async function getDummySigner(chainId: number): Promise {
const config = getOceanConfig(chainId)
@@ -36,8 +35,9 @@ export async function getDummySigner(chainId: number): Promise {
------------------------------------------ */
function getWagmiChains(): readonly [Chain, ...Chain[]] {
const baseChains: Chain[] = [...getSupportedChains(chainIdsSupported)]
+ const runtimeConfig = getRuntimeConfig()
- if (process.env.NEXT_PUBLIC_MARKET_DEVELOPMENT === 'true') {
+ if (runtimeConfig.NEXT_PUBLIC_MARKET_DEVELOPMENT === 'true') {
baseChains.push({ ...localhost, id: 11155420 })
}
diff --git a/src/@utils/wallet/policyServer.ts b/src/@utils/wallet/policyServer.ts
index da9100b8d..f9cc06586 100644
--- a/src/@utils/wallet/policyServer.ts
+++ b/src/@utils/wallet/policyServer.ts
@@ -22,7 +22,10 @@ export async function requestCredentialPresentation(
policyServerData: PolicyServerInitiateActionData
}> {
try {
- const sessionId = crypto.randomUUID()
+ const sessionId =
+ typeof globalThis.crypto?.randomUUID === 'function'
+ ? globalThis.crypto.randomUUID()
+ : `${Date.now()}-${Math.random().toString(16).slice(2)}`
const policyServer: PolicyServerInitiateActionData = {
sessionId,
successRedirectUri: ``,
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 92c6e48ce..a70c339f1 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,5 +1,6 @@
'use client'
import type { AppProps } from 'next/app'
+import Script from 'next/script'
import { ReactElement, useEffect, useState } from 'react'
import { UserPreferencesProvider } from '@context/UserPreferences'
import UrqlProvider from '@context/UrqlProvider'
@@ -31,6 +32,7 @@ function MyApp({ Component, pageProps }: AppProps): ReactElement {
return (
+
+
+
+
+
+
+
+
+