fix: normalize production configs, types, and cross-platform frontend build
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m29s
CI/CD Pipeline / Security Scanning (push) Successful in 2m40s
CI/CD Pipeline / Lint and Format (push) Failing after 46s
CI/CD Pipeline / Terraform Validation (push) Failing after 26s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 26s
Validation / validate-genesis (push) Successful in 27s
Validation / validate-terraform (push) Failing after 28s
Validation / validate-kubernetes (push) Failing after 12s
Validation / validate-smart-contracts (push) Failing after 13s
Validation / validate-security (push) Failing after 1m17s
Validation / validate-documentation (push) Failing after 18s

Repair double-spaced source files, align middleware/exchange types with production JSON, and fix vite build on Windows/Linux.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-28 14:45:38 -07:00
parent ab1c46787b
commit 33e93165f6
7 changed files with 28 additions and 390 deletions

View File

@@ -1,53 +1,26 @@
{
"$schema": "DBIS Exchange — production (128-chain OMNL Bank)",
"version": "1.0.0",
"chainId": 138,
"brandName": "DBIS Exchange",
"officeId": 24,
"settlementOfficeExternalId": "HOSPITALLERS-ALI-IRAQ-IRAN",
"chainRegistry": "config/omnl-supported-chains.v1.json",
"maxSupportedChains": 128,
"routers": {
"enhancedSwapRouterV2": "0xa421706768aeb7fafa2d912c5e10824ef3437ad4",
"uniswapV2": "0x3019A7fDc76ba7F64F18d78e66842760037ee638",
"sushiV2": "0xB37b93D38559f53b62ab020A14919f2630a1aE34"
},
"factory": {
"uniswapV2": "0x0C30F6e67Ab3667fCc2f5CEA8e274ef1FB920279"
},
"tokens": [],
"defaultSlippageBps": 50,
"production": {
"requireApiKey": true,
"monitorSwaps": true,
"postSwapSettlementAudit": true,
"onlineBankMode": true
}
}

View File

@@ -1,69 +1,48 @@
{
"$schema": "OMNL central-bank settlement — production profile",
"version": "1.0.0",
"omnlLegalName": "ORGANISATION MONDIALE DU NUMERIQUE L.P.B.C.",
"defaultOfficeId": 24,
"enforceSingleOffice": true,
"settlementOffice": {
"officeId": 24,
"externalId": "HOSPITALLERS-ALI-IRAQ-IRAN",
"name": "HOSPITALLERS Ali Iraq-Iran",
"profilePath": "config/offices/office-24-settlement.v1.json"
},
"defaultCurrency": "USD",
"chainRegistry": "config/omnl-supported-chains.v1.json",
"maxSupportedChains": 128,
"rails": {
"swift": { "enabled": true, "listenerUrl": "http://192.168.11.114:8788" },
"hybx": { "enabled": true, "sidecarUrl": "http://192.168.11.89:8080" },
"chain138": { "enabled": true, "rpcEnv": "RPC_URL_138", "defaultLineId": "USD-M2" },
"multiChain": { "enabled": true, "registryPath": "config/omnl-supported-chains.v1.json", "primaryChainId": 138 }
"swift": {
"enabled": true,
"listenerUrl": "http://192.168.11.114:8788"
},
"hybx": {
"enabled": true,
"sidecarUrl": "http://192.168.11.89:8080"
},
"chain138": {
"enabled": true,
"rpcEnv": "RPC_URL_138",
"defaultLineId": "USD-M2"
},
"multiChain": {
"enabled": true,
"registryPath": "config/omnl-supported-chains.v1.json",
"primaryChainId": 138
}
},
"moneySupply": {
"glM0": "1050",
"glM1": "2100",
"glM2": "2200",
"glSettlement": "1000"
},
"production": {
"requireApiKey": true,
"allowHybxProduction": true,
"allowChainMintExecute": true,
"onlineBankMode": true
}
}

View File

@@ -4,7 +4,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "NODE_OPTIONS='--max-old-space-size=4096' vite build",
"build": "node --max-old-space-size=4096 ./node_modules/vite/bin/vite.js build",
"build:check": "tsc && NODE_OPTIONS='--max-old-space-size=4096' vite build",
"preview": "vite preview",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",

View File

@@ -1,141 +1,60 @@
/** DBIS Exchange — Chain 138 DEX addresses (Pancake/Uniswap V2 compatible) */
export const DBIS_EXCHANGE_CHAIN_ID = 138;
export const TOKEN_AGGREGATION_URL =
import.meta.env.VITE_TOKEN_AGGREGATION_URL || 'http://localhost:3000';
export const DBIS_EXCHANGE_URL =
import.meta.env.VITE_DBIS_EXCHANGE_URL || 'http://localhost:3012';
export const SETTLEMENT_MIDDLEWARE_URL =
import.meta.env.VITE_SETTLEMENT_MIDDLEWARE_URL || 'http://localhost:3011';
export const ENHANCED_SWAP_ROUTER_V2 =
import.meta.env.VITE_ENHANCED_SWAP_ROUTER_V2 ||
'0xa421706768aeb7fafa2d912c5e10824ef3437ad4';
export const UNISWAP_V2_ROUTER_138 =
import.meta.env.VITE_UNISWAP_V2_ROUTER_138 ||
'0x3019A7fDc76ba7F64F18d78e66842760037ee638';
export type DexToken = {
symbol: string;
name: string;
address: string;
decimals: number;
native?: boolean;
omnlLine?: string;
moneyLayer?: string;
currencyCode?: string;
swappable?: boolean;
convertible?: boolean;
transferableInternal?: boolean;
transferableExternal?: boolean;
};
/** Fallback when exchange API unavailable */
export const DEFAULT_TOKENS: DexToken[] = [
{ symbol: 'ETH', name: 'Ether', address: '0x0000000000000000000000000000000000000000', decimals: 18, native: true, omnlLine: 'USD-M2', moneyLayer: 'M2' },
{ symbol: 'WETH', name: 'Wrapped Ether', address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', decimals: 18, omnlLine: 'USD-M2', moneyLayer: 'M2' },
{ symbol: 'USDT', name: 'Tether USD', address: '0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1', decimals: 6, omnlLine: 'USD-M2', moneyLayer: 'M2' },
{ symbol: 'USDC', name: 'USD Coin', address: '0x71D6687F38b93CCad569Fa6352c876eea967201b', decimals: 6, omnlLine: 'USD-M2', moneyLayer: 'M2' },
{ symbol: 'cUSDT', name: 'Compliant USDT', address: '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22', decimals: 6, omnlLine: 'USD-M2', moneyLayer: 'M2' },
{ symbol: 'cUSDC', name: 'Compliant USDC', address: '0xf22258f57794CC8E06237084b353Ab30fFfa640b', decimals: 6, omnlLine: 'USD-M2', moneyLayer: 'M2' },
];
export function parseAmountToWei(amount: string, decimals: number): string {
const [whole, frac = ''] = amount.split('.');
const padded = (frac + '0'.repeat(decimals)).slice(0, decimals);
return BigInt(`${whole}${padded}` || '0').toString();
}
export function formatAmountFromWei(wei: string, decimals: number): string {
const v = BigInt(wei || '0');
const base = 10n ** BigInt(decimals);
const whole = v / base;
const frac = v % base;
if (frac === 0n) return whole.toString();
return `${whole}.${frac.toString().padStart(decimals, '0').replace(/0+$/, '')}`;
}
export async function fetchExchangeTokens(): Promise<DexToken[]> {
try {
const res = await fetch(`${DBIS_EXCHANGE_URL.replace(/\/$/, '')}/api/v1/exchange/tokens`);
if (!res.ok) return DEFAULT_TOKENS;
const data = await res.json();
return Array.isArray(data.tokens) && data.tokens.length > 0 ? data.tokens : DEFAULT_TOKENS;
} catch {
return DEFAULT_TOKENS;
}
}

View File

@@ -1,317 +1,150 @@
import axios from 'axios';
import { JsonRpcProvider, Contract, formatUnits } from 'ethers';
import { settlementUrl } from '../config';
import type { M2TokenCapabilities } from '@dbis/settlement-core';
const ERC20_ABI = ['function balanceOf(address) view returns (uint256)', 'function decimals() view returns (uint8)'];
export async function fetchFundLedger(officeId: number, apiKey?: string) {
const headers: Record<string, string> = {};
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
const { data } = await axios.get(`${settlementUrl()}/api/v1/settlement/money-supply`, {
headers,
timeout: 60000,
});
return { officeId, fundLedger: data };
}
export async function fetchOfficeProfile() {
const { data } = await axios.get(`${settlementUrl()}/api/v1/settlement/office`, { timeout: 15000 });
return data;
}
export async function auditSwapToSettlement(payload: {
idempotencyKey: string;
amount: string;
currency: string;
recipientAddress: string;
remittanceInfo: string;
tokenLineId?: string;
apiKey?: string;
}) {
const lineId = payload.tokenLineId ?? `${payload.currency}-M2`;
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (payload.apiKey) headers.Authorization = `Bearer ${payload.apiKey}`;
const { data } = await axios.post(
`${settlementUrl()}/api/v1/settlement/convert/fiat-to-crypto`,
{
idempotencyKey: payload.idempotencyKey,
amount: payload.amount,
currency: payload.currency,
creditorIban: 'GB82WEST12345698765432',
beneficiaryName: 'DBIS Exchange settlement audit',
remittanceInfo: payload.remittanceInfo,
convertToCrypto: {
enabled: true,
targetChainId: 138,
tokenLineId: lineId,
recipientAddress: payload.recipientAddress,
},
},
{ headers, timeout: 120000, validateStatus: () => true },
);
return data;
}
export async function requestM2TokenLoad(payload: {
idempotencyKey: string;
lineId: string;
symbol: string;
tokenAddress: string;
amount: string;
recipientAddress: string;
currency?: string;
apiKey?: string;
}) {
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (payload.apiKey) headers.Authorization = `Bearer ${payload.apiKey}`;
const { data } = await axios.post(
`${settlementUrl()}/api/v1/settlement/token-load`,
{
idempotencyKey: payload.idempotencyKey,
lineId: payload.lineId,
symbol: payload.symbol,
tokenAddress: payload.tokenAddress,
amount: payload.amount,
recipientAddress: payload.recipientAddress,
currency: payload.currency,
},
{ headers, timeout: 120000, validateStatus: () => true },
);
return data;
}
export async function requestInternalTransfer(payload: {
idempotencyKey: string;
tokenAddress: string;
tokenSymbol: string;
amount: string;
recipientAddress: string;
senderAddress?: string;
apiKey?: string;
}) {
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (payload.apiKey) headers.Authorization = `Bearer ${payload.apiKey}`;
const { data } = await axios.post(
`${settlementUrl()}/api/v1/settlement/transfer/internal`,
{
...payload,
moneyLayers: ['M2'],
},
{ headers, timeout: 120000, validateStatus: () => true },
);
return data;
}
export async function requestExternalTransfer(payload: {
idempotencyKey: string;
tokenAddress: string;
tokenSymbol: string;
amount: string;
recipientAddress: string;
creditorIban: string;
beneficiaryName?: string;
currency?: string;
remittanceInfo?: string;
apiKey?: string;
}) {
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (payload.apiKey) headers.Authorization = `Bearer ${payload.apiKey}`;
const { data } = await axios.post(
`${settlementUrl()}/api/v1/settlement/transfer/external`,
{
...payload,
moneyLayers: ['M2'],
rail: 'SWIFT',
},
{ headers, timeout: 120000, validateStatus: () => true },
);
return data;
}
export async function fetchCryptoLedger(
rpcUrl: string,
wallet: string,
tokens: { address: string; symbol: string; decimals: number; native?: boolean }[],
) {
const provider = new JsonRpcProvider(rpcUrl);
const balances: Record<string, string> = {};
for (const t of tokens) {
if (t.native || t.address === '0x0000000000000000000000000000000000000000') {
const wei = await provider.getBalance(wallet);
balances[t.symbol] = formatUnits(wei, 18);
continue;
}
try {
const c = new Contract(t.address, ERC20_ABI, provider);
const raw = await c.balanceOf(wallet);
balances[t.symbol] = formatUnits(raw, t.decimals);
} catch {
balances[t.symbol] = '0';
}
}
return { wallet, balances };
}
export function resolveTokenLine(token: M2TokenCapabilities): string {
return token.omnlLine;
}

View File

@@ -1,149 +1,77 @@
import fs from 'fs';
import path from 'path';
import {
mergeExchangeTokensWithM2Registry,
type M2TokenCapabilities,
type M2TokenRegistryFile,
} from '@dbis/settlement-core';
export type ExchangeConfig = {
version: string;
chainId: number;
brandName: string;
officeId: number;
settlementOfficeExternalId: string;
chainRegistry?: string;
maxSupportedChains?: number;
routers: Record<string, string>;
factory: Record<string, string>;
tokens: {
symbol: string;
name: string;
address: string;
decimals: number;
native?: boolean;
omnlLine?: string;
moneyLayer?: string;
swappable?: boolean;
convertible?: boolean;
transferableInternal?: boolean;
transferableExternal?: boolean;
}[];
defaultSlippageBps: number;
production: {
requireApiKey: boolean;
monitorSwaps: boolean;
postSwapSettlementAudit: boolean;
onlineBankMode?: boolean;
};
};
let cached: ExchangeConfig | null = null;
let cachedM2: M2TokenRegistryFile | null = null;
export function loadM2TokenRegistry(): M2TokenRegistryFile {
if (cachedM2) return cachedM2;
const p =
process.env.OMNL_M2_TOKEN_REGISTRY ||
path.resolve(__dirname, '../../../config/omnl-m2-token-registry.v1.json');
cachedM2 = JSON.parse(fs.readFileSync(p, 'utf8')) as M2TokenRegistryFile;
return cachedM2;
}
export function loadExchangeTokens(): M2TokenCapabilities[] {
const cfg = loadExchangeConfig();
return mergeExchangeTokensWithM2Registry(cfg.tokens, loadM2TokenRegistry());
}
export function loadExchangeConfig(): ExchangeConfig {
if (cached) return cached;
const p =
process.env.DBIS_EXCHANGE_CONFIG ||
path.resolve(__dirname, '../../../config/dbis-exchange.v1.json');
cached = JSON.parse(fs.readFileSync(p, 'utf8')) as ExchangeConfig;
return cached;
}
export function exchangePort(): number {
return parseInt(process.env.DBIS_EXCHANGE_PORT || '3012', 10);
}
export function tokenAggUrl(): string {
return (process.env.TOKEN_AGGREGATION_URL || 'http://localhost:3000').replace(/\/$/, '');
}
export function settlementUrl(): string {
return (process.env.SETTLEMENT_MIDDLEWARE_URL || 'http://localhost:3011').replace(/\/$/, '');
}

View File

@@ -41,6 +41,11 @@ export type MiddlewareConfig = {
swift: { enabled: boolean; listenerUrl: string };
hybx: { enabled: boolean; sidecarUrl: string };
chain138: { enabled: boolean; rpcEnv: string; defaultLineId: string };
multiChain?: {
enabled: boolean;
registryPath: string;
primaryChainId: number;
};
};
moneySupply: {
glM0: string;
@@ -52,6 +57,7 @@ export type MiddlewareConfig = {
requireApiKey: boolean;
allowHybxProduction: boolean;
allowChainMintExecute: boolean;
onlineBankMode?: boolean;
};
};