Files
explorer-monorepo/frontend/src/services/api/gruCatalog.ts
defiQUG f46bd213ba refactor: rename SolaceScanScout to Solace and update related configurations
- Updated branding from "SolaceScanScout" to "Solace" across various files including deployment scripts, API responses, and documentation.
- Changed default base URL for Playwright tests and updated security headers to reflect the new branding.
- Enhanced README and API documentation to include new authentication endpoints and product access details.

This refactor aligns the project branding and improves clarity in the API documentation.
2026-04-10 12:52:17 -07:00

117 lines
3.0 KiB
TypeScript

export interface GruCatalogPosture {
isGru: boolean
isWrappedTransport: boolean
isX402Ready: boolean
isForwardCanonical: boolean
currencyCode?: string
activeVersion?: string
forwardVersion?: string
}
interface GruCatalogEntry extends GruCatalogPosture {
symbol: string
addresses?: string[]
}
const GRU_X402_READY_SYMBOLS = new Set([
'CAUDC',
'CCADC',
'CCHFC',
'CEURC',
'CEURT',
'CGBPC',
'CGBPT',
'CJPYC',
'CUSDC',
'CUSDT',
'CXAUC',
'CXAUT',
])
const GRU_CATALOG: GruCatalogEntry[] = [
{
symbol: 'cUSDC',
currencyCode: 'USD',
isGru: true,
isWrappedTransport: false,
isX402Ready: true,
isForwardCanonical: true,
activeVersion: 'v1',
forwardVersion: 'v2',
addresses: [
'0xf22258f57794cc8e06237084b353ab30fffa640b',
'0x219522c60e83dee01fc5b0329d6fa8fd84b9d13d',
],
},
{
symbol: 'cUSDT',
currencyCode: 'USD',
isGru: true,
isWrappedTransport: false,
isX402Ready: true,
isForwardCanonical: true,
activeVersion: 'v1',
forwardVersion: 'v2',
addresses: [
'0x93e66202a11b1772e55407b32b44e5cd8eda7f22',
'0x9fbfab33882efe0038daa608185718b772ee5660',
],
},
...['cAUDC', 'cCADC', 'cCHFC', 'cEURC', 'cEURT', 'cGBPC', 'cGBPT', 'cJPYC', 'cXAUC', 'cXAUT'].map((symbol) => ({
symbol,
currencyCode: symbol.slice(1, 4).replace('XAU', 'XAU'),
isGru: true,
isWrappedTransport: false,
isX402Ready: true,
isForwardCanonical: true,
forwardVersion: 'v2',
})),
]
function normalizeSymbol(symbol?: string | null): string {
return (symbol || '').trim().toUpperCase()
}
function normalizeAddress(address?: string | null): string {
return (address || '').trim().toLowerCase()
}
export function getGruCatalogPosture(input: {
symbol?: string | null
address?: string | null
tags?: string[] | null
}): GruCatalogPosture | null {
const symbol = normalizeSymbol(input.symbol)
const address = normalizeAddress(input.address)
const tags = (input.tags || []).map((tag) => tag.toLowerCase())
const matched = GRU_CATALOG.find((entry) => {
if (symbol && normalizeSymbol(entry.symbol) === symbol) return true
if (address && entry.addresses?.includes(address)) return true
return false
})
if (matched) {
return {
isGru: true,
isWrappedTransport: matched.isWrappedTransport,
isX402Ready: matched.isX402Ready,
isForwardCanonical: matched.isForwardCanonical,
currencyCode: matched.currencyCode,
activeVersion: matched.activeVersion,
forwardVersion: matched.forwardVersion,
}
}
const looksWrapped = symbol.startsWith('CW')
const looksGru = looksWrapped || symbol.startsWith('C') || tags.includes('compliant') || tags.includes('wrapped') || tags.includes('bridge')
if (!looksGru) return null
return {
isGru: true,
isWrappedTransport: looksWrapped || tags.includes('wrapped') || tags.includes('bridge'),
isX402Ready: GRU_X402_READY_SYMBOLS.has(symbol),
isForwardCanonical: GRU_X402_READY_SYMBOLS.has(symbol) && !looksWrapped,
}
}