Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
3d7cb9a
chore: init
AdriGeorge Dec 10, 2025
19c8962
chore: init
AdriGeorge Dec 10, 2025
3ddbbc1
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 10, 2025
b340778
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 12, 2025
3cc7791
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 12, 2025
af8bca1
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 15, 2025
09e4c27
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 15, 2025
51487cd
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 15, 2025
9fe9150
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 15, 2025
6a81b04
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Dec 19, 2025
68130a8
Merge remote-tracking branch 'origin/feat/stage' into feat/multi-token
ahmedraza118 Dec 22, 2025
44da47b
fix multi token in publish pricing
ahmedraza118 Dec 22, 2025
d939068
refactor: use nextjs built Link for internal links
tom1145 Dec 29, 2025
7f9be82
refactor: use Link
tom1145 Dec 29, 2025
e8dcca1
Merge branch 'feat/multi-token-ahmed' into feat/multi-token-profile
tom1145 Dec 29, 2025
fdf6acd
fix: chose token on add service
ahmedraza118 Dec 29, 2025
af484de
form initial price value set to 1
ahmedraza118 Jan 5, 2026
96aa3d1
chore: normal buy and order
AdriGeorge Jan 5, 2026
e41aae3
Merge pull request #227 from OceanProtocolEnterprise/feat/multi-token…
AdriGeorge Jan 5, 2026
e37af92
Merge branch 'feat/multi-token' of https://github.com/OceanProtocolEn…
AdriGeorge Jan 5, 2026
b1b3cee
chore: fix
AdriGeorge Jan 5, 2026
7ddcdf4
fix: fix
AdriGeorge Jan 5, 2026
a87f7e4
feat: enhance profile and escrow functionality with multi-token support
tom1145 Jan 6, 2026
cad4b3d
Merge pull request #228 from OceanProtocolEnterprise/feat/normal-buy-…
AdriGeorge Jan 6, 2026
443ac94
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Jan 6, 2026
5f4b2a2
Merge branch 'feat/multi-token' into feat/multi-token-profile
tom1145 Jan 6, 2026
afc0d0b
fix: build
tom1145 Jan 6, 2026
9494887
refactor: remove unused symbol return in getBaseTokenSymbol function
tom1145 Jan 6, 2026
c37dadc
fix: build
tom1145 Jan 6, 2026
5fcfadd
style: update CoinSelect and InputElement styles
tom1145 Jan 6, 2026
72a5285
fix: history no results
tom1145 Jan 6, 2026
601cb2e
style: adjust update selectorLabel styles
tom1145 Jan 6, 2026
e0a7795
style: fix columns history table
tom1145 Jan 6, 2026
209bf85
refactor: asset price and token symbol
tom1145 Jan 8, 2026
15b59e7
refactor: remove totalRevenue
tom1145 Jan 8, 2026
a98df9f
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Jan 8, 2026
b2e90f8
refactor: show token symbol in eport data
tom1145 Jan 8, 2026
16e5f61
Merge pull request #230 from OceanProtocolEnterprise/feat/multi-token…
tom1145 Jan 8, 2026
4e4ab19
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Jan 13, 2026
685af4e
fix: fix env
AdriGeorge Jan 14, 2026
1d44b51
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Jan 14, 2026
3248ee3
chore: fees
AdriGeorge Jan 14, 2026
24af8c6
Merge branch 'feat/stage' of https://github.com/OceanProtocolEnterpri…
AdriGeorge Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
# NEXT_PUBLIC_INFURA_PROJECT_ID=
# NEXT_PUBLIC_ESCROW_ADDRESSES={"11155111":"0x5494711392a67DA50D3bC7b1fcC2d1877cFaA4d2", "11155420":"0x4D49eEedFac8Ea03328c0E4871b680C06d892092"}
# NEXT_PUBLIC_NODE_URI_MAP={"1":"https://mainnet...", "10":"https://optimism...", "11155111":"https://eth-sepolia.g.alchemy.com/.., "11155420":"https://opt-sepolia.g.alchemy.com/..}
# NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE=1500000000000000000
# NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE_MAP={"11155111":[{"token":"0x1B083D8584dd3e6Ff37d04a6e7e82b5F622f3985","amount":"1500000000000000000"}, {"token": "0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4", "amount": "2000000"}]}
# NEXT_PUBLIC_CONSUME_MARKET_FEE=0.1
# NEXT_PUBLIC_MARKET_FEE_ADDRESS=0x0db00a90deee402256cb1df89f3e14d6b9130fdd
5 changes: 2 additions & 3 deletions app.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ module.exports = {

// consume market fee that is taken upon ordering an asset, it is an absolute value with 18 decimals, it is specified on order
consumeMarketOrderFee:
getEnv('NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE') ||
process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE ||
'0',
getEnv('NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE_MAP') ||
process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE_MAP,
consumeMarketFee:
getEnv('NEXT_PUBLIC_CONSUME_MARKET_FEE') ||
process.env.NEXT_PUBLIC_CONSUME_MARKET_FEE ||
Expand Down
6 changes: 3 additions & 3 deletions scripts/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ const config = {
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_CONSUME_MARKET_ORDER_FEE_MAP:
process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE_MAP,
NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS:
process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
NEXT_PUBLIC_DISPENSER_ADDRESS: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
Expand All @@ -39,7 +39,7 @@ const config = {
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
NEXT_PUBLIC_ALLOWED_ERC20_ADDRESSES: process.env.NEXT_PUBLIC_ALLOWED_ERC20_ADDRESSES
}

fs.writeFileSync(
Expand Down
7 changes: 4 additions & 3 deletions scripts/write-runtime-config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ const config = {
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_CONSUME_MARKET_ORDER_FEE_MAP:
process.env.NEXT_PUBLIC_CONSUME_MARKET_ORDER_FEE_MAP,
NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS:
process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS,
NEXT_PUBLIC_DISPENSER_ADDRESS: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS,
Expand All @@ -58,7 +58,8 @@ const config = {
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
NEXT_PUBLIC_ALLOWED_ERC20_ADDRESSES:
process.env.NEXT_PUBLIC_ALLOWED_ERC20_ADDRESSES
}

const outputPath = path.join(process.cwd(), 'public', 'runtime-config.js')
Expand Down
13 changes: 10 additions & 3 deletions src/@context/MarketMetadata/_types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
export interface OpcFee {
chainId: number
export interface OpcTokenData {
tokenAddress: string
feePercentage: string
maxFee: string
minFee: string
approvedTokens: string[]
approved: boolean
}

export interface OpcFee {
chainId: number
// Instead of a single fee, we have an array of fee data per token
tokensData: OpcTokenData[]
}

export interface AppConfig {
Expand All @@ -16,6 +22,7 @@ export interface AppConfig {
publisherMarketFixedSwapFee: string
consumeMarketOrderFee: string
consumeMarketFixedSwapFee: string
customProviderUrl?: string
allowFixedPricing: string
allowDynamicPricing: string
allowFreePricing: string
Expand Down
74 changes: 48 additions & 26 deletions src/@context/MarketMetadata/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import {
import { MarketMetadataProviderValue, OpcFee } from './_types'
import siteContent from '../../../content/site.json'
import appConfig from '../../../app.config.cjs'
import { LoggerInstance } from '@oceanprotocol/lib'
import { useConnect, useChainId } from 'wagmi'
import { getOceanConfig } from '@utils/ocean'
import { getTokenInfo } from '@utils/wallet'
import useEnterpriseFeeColletor from '@hooks/useEnterpriseFeeCollector'
import { useEthersSigner } from '@hooks/useEthersSigner'

const MarketMetadataContext = createContext({} as MarketMetadataProviderValue)

function MarketMetadataProvider({
Expand All @@ -28,27 +28,28 @@ function MarketMetadataProvider({
const chainId = useChainId()
const signer = useEthersSigner()

const { getOpcData } = useEnterpriseFeeColletor()
const { getOpcData, enterpriseFeeCollector } = useEnterpriseFeeColletor()
const [opcFees, setOpcFees] = useState<OpcFee[]>()
const [approvedBaseTokens, setApprovedBaseTokens] = useState<TokenInfo[]>()

const config = getOceanConfig(chainId)

// ---------------------------
// Load OPC Fee Data
// ---------------------------
useEffect(() => {
async function fetchData() {
// Safety check: Don't run if we don't have a signer yet
if (!signer) return

const opcData = await getOpcData(appConfig.chainIdsSupported)
LoggerInstance.log('[MarketMetadata] Got new data.', {
opcFees: opcData,
siteContent,
appConfig
})
setOpcFees(opcData)
}

if (signer) fetchData()
}, [signer])
if (!opcFees && signer && enterpriseFeeCollector) {
fetchData()
}
}, [signer, getOpcData, enterpriseFeeCollector])

// ---------------------------
// Get OPC fee for given token
Expand All @@ -57,38 +58,58 @@ function MarketMetadataProvider({
(tokenAddress: string, chainId: number): string => {
if (!opcFees) return '0'
const opc = opcFees.find((x) => x.chainId === chainId)
return opc?.feePercentage || '0'
return (
opc?.tokensData.find(
(x) => x.tokenAddress.toLowerCase() === tokenAddress.toLowerCase()
)?.feePercentage || '0'
)
},
[opcFees]
)

// ---------------------------
// Load OCEAN token metadata
// Load approved tokens metadata
// ---------------------------

const tokenAddressesString = JSON.stringify(config?.tokenAddresses || [])

useEffect(() => {
async function fetchTokenInfoSafe() {
const addresses = JSON.parse(tokenAddressesString)

try {
if (isLoading) return
if (!config?.oceanTokenAddress) {
console.warn('[fetchTokenInfo] No oceanTokenAddress configured.')
return
}

if (!chainId) {
console.error('[fetchTokenInfo] chainId missing.')
if (!addresses || addresses.length === 0) {
return
}

if (!signer) {
console.warn('[fetchTokenInfo] Waiting for signer...')
return
}
const tokenDetails = await getTokenInfo(
config.oceanTokenAddress,
signer.provider
if (!chainId) return
if (!signer) return

// 1. Fetch metadata for all configured tokens
const tokenPromises = addresses.map((address: string) =>
getTokenInfo(address, signer.provider)
)

setApprovedBaseTokens([tokenDetails])
const tokensDetails = await Promise.all(tokenPromises)
// 2. Identify allowed tokens from OPC Data for the current chain
const currentChainOpc = opcFees?.find((x) => x.chainId === chainId)

// Create a Set of allowed addresses (normalized to lowercase) for fast lookup
const allowedAddresses = new Set(
currentChainOpc?.tokensData.map((t) =>
t.tokenAddress.toLowerCase()
) || []
)
// 3. Filter: Keep only valid tokens that ARE ALSO in the allowed list
const filteredTokens = tokensDetails.filter((t) => {
if (!t) return false // Filter out undefined fetch results

return allowedAddresses.has(t.address.toLowerCase())
})

setApprovedBaseTokens(filteredTokens)
} catch (error: any) {
console.error(
'[fetchTokenInfo] Error fetching token info:',
Expand All @@ -97,8 +118,9 @@ function MarketMetadataProvider({
}
}

// added opcFees to dependency so it refilters when fee data arrives
fetchTokenInfoSafe()
}, [isLoading, chainId, signer, config?.oceanTokenAddress])
}, [isLoading, chainId, signer, tokenAddressesString, opcFees])

return (
<MarketMetadataContext.Provider
Expand Down
Loading