Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 34 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ── Supabase ──────────────────────────────────────────────────────────────────
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# ── OpenAI ────────────────────────────────────────────────────────────────────
OPENAI_API_KEY=sk-...

# ── Blockchain / Viem ─────────────────────────────────────────────────────────
VIEM_PRIVATE_KEY=0x... # Operator wallet private key
BASE_RPC_URL=https://mainnet.base.org # Optional: override default Base RPC

# ── Superfluid (Base mainnet) ─────────────────────────────────────────────────
SUPERFLUID_HOST_ADDRESS=0x4C073B8641AB798b3197b8B1E3bb33bB92D16Aa
SUPERFLUID_CFA_ADDRESS=0x19ba78B9cDB05A877718841c574325fdB53601bb
SUPERFLUID_GDA_ADDRESS=0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08
SUPERFLUID_USDCX_ADDRESS=0xD04383398dD2426297da660F9CCA3d439AF9ce1b

# ── Payment ───────────────────────────────────────────────────────────────────
SETTLEMENT_ADDRESS=0x7bEda57074AA917FF0993fb329E16C2c188baF08
X402_PAYMENT_AMOUNT=0.15
X402_FLOW_RATE=1929012345679 # ~$5/month in wei/sec

# ── External APIs ─────────────────────────────────────────────────────────────
GOOGLE_MAPS_API_KEY=AIza...
DUNE_API_KEY=...
ARKHAM_API_KEY=...
# Note: DefiLlama is public — no API key required

# ── Auth ──────────────────────────────────────────────────────────────────────
JWT_SECRET=change-this-to-a-long-random-string-in-production

# ── Server ────────────────────────────────────────────────────────────────────
PORT=3000
NODE_ENV=production
143 changes: 91 additions & 52 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,107 @@
import 'dotenv/config';
import express from 'express';
import cors from 'cors';

// ── Middleware ────────────────────────────────────────────────────────────────
import {
corsOptions,
globalRateLimit,
strictRateLimit,
requestLogger,
errorHandler,
} from './src/middleware/index.js';

// ── Route handlers ────────────────────────────────────────────────────────────
import marketRouter from './src/routes/market.js';
import scriptureRouter from './src/routes/scripture.js';
import churchesRouter from './src/routes/churches.js';
import streamsRouter from './src/routes/streams.js';
import validatorsRouter from './src/routes/validators.js';
import x402Router from './src/routes/x402.js';
import mcpRouter from './src/routes/mcp.js';
import a2aRouter from './src/routes/a2a.js';

// ── Background jobs ───────────────────────────────────────────────────────────
import { registerJobs } from './src/jobs/index.js';

const app = express();
const PORT = process.env.PORT || 3000;

const BASE_APP_ID = '69c77ff3f832953fc6c8fd14';
const RAILWAY_URL = 'https://biblefi-api-production.up.railway.app';
// ── Core middleware ───────────────────────────────────────────────────────────
app.use(cors(corsOptions));
app.use(express.json({ limit: '1mb' }));
app.use(requestLogger);
app.use(globalRateLimit);

app.use(cors({ origin: '*', methods: ['GET', 'POST', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'] }));
app.use(express.json());

// Root — serves HTML page with base:app_id, fc:frame, og meta tags
// ── Health / discovery ────────────────────────────────────────────────────────
app.get('/', (req, res) => {
const html = [
'<!DOCTYPE html>',
'<html lang="en">',
'<head>',
'<meta charset="UTF-8">',
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
'<title>BibleFi - Biblical DeFi on Base</title>',
`<meta name="base:app_id" content="${BASE_APP_ID}">`,
`<meta property="og:title" content="BibleFi - Biblical DeFi on Base">`,
`<meta property="og:description" content="Biblical wisdom meets DeFi on Base Chain.">`,
`<meta property="og:url" content="${RAILWAY_URL}">`,
`<meta property="og:type" content="website">`,
`<meta property="fc:frame" content="vNext">`,
`<meta property="fc:frame:image" content="${RAILWAY_URL}/og-image.png">`,
`<meta property="fc:frame:image:aspect_ratio" content="1.91:1">`,
`<meta property="fc:frame:button:1" content="Enter BibleFi">`,
`<meta property="fc:frame:button:1:action" content="link">`,
`<meta property="fc:frame:button:1:target" content="${RAILWAY_URL}">`,
`<meta property="fc:frame:post_url" content="${RAILWAY_URL}/api/frame">`,
'</head>',
'<body style="margin:0;background:#0a0a0a;color:#f5f5f5;font-family:monospace;display:flex;align-items:center;justify-content:center;min-height:100vh;flex-direction:column;gap:1rem;">',
'<h1 style="color:#f0c040;font-size:2rem;">BibleFi</h1>',
'<p style="color:#aaa;max-width:400px;text-align:center;">Biblical Wisdom To Yield Algorithm Agent - ERC-8004 on Base Chain</p>',
'<code style="background:#111;padding:.5rem 1rem;border-radius:6px;color:#4ade80;">Status: operational</code>',
'</body>',
'</html>'
].join('\n');

res.status(200).setHeader('Content-Type', 'text/html; charset=utf-8').send(html);
res.json({
agent: 'BWTYAA - Biblical Wisdom To Yield Algorithm Agent',
version: '2.0.0',
status: 'operational',
operator: 'normancomics.eth',
network: 'base',
chainId: 8453,
timestamp: new Date().toISOString(),
endpoints: {
a2a: '/a2a',
mcp: '/mcp',
x402: '/x402',
market: '/v1/market',
scripture:'/v1/scripture-match',
churches: '/v1/churches',
streams: '/v1/streams',
validators:'/v1/validators',
private: '/v1/private',
},
protocols: ['A2A', 'MCP', 'x402', 'ERC-8004'],
});
});

// Farcaster Frame POST handler
app.post('/api/frame', (req, res) => {
res.json({ version: 'vNext', image: `${RAILWAY_URL}/og-image.png`, buttons: [{ label: 'Enter BibleFi', action: 'link', target: RAILWAY_URL }] });
// ── Protocol endpoints ────────────────────────────────────────────────────────
app.use('/a2a', a2aRouter);
app.use('/mcp', mcpRouter);
app.use('/x402', x402Router);

// ── v1 API endpoints ──────────────────────────────────────────────────────────
app.use('/v1/market', strictRateLimit, marketRouter);
app.use('/v1/scripture-match', strictRateLimit, scriptureRouter);
app.use('/v1/churches', churchesRouter);
app.use('/v1/streams', streamsRouter);
app.use('/v1/validators', validatorsRouter);

// ── /v1/private (placeholder — ZKP / veil.cash integration) ──────────────────
app.post('/v1/private', (req, res) => {
res.json({
capability: 'privacy_transactions',
status: 'coming_soon',
privacy_tech: {
zkp_language: 'Noir',
protocol: 'veil.cash',
},
});
});

// JSON API info endpoint
app.get('/api', (req, res) => {
res.json({ agent: 'BWTYAA - Biblical Wisdom To Yield Algorithm Agent', version: '2.0.0', status: 'operational', operator: 'normancomics.eth', timestamp: new Date().toISOString(), base_app_id: BASE_APP_ID, endpoints: { a2a: '/a2a', mcp: '/mcp', x402: '/x402', market: '/v1/market', scripture: '/v1/scripture-match', churches: '/v1/churches', streams: '/v1/streams', private: '/v1/private' } });
// ── 404 handler ───────────────────────────────────────────────────────────────
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
message: `${req.method} ${req.path} is not a valid endpoint`,
docs: 'https://biblefi-api-production.up.railway.app/',
});
});

app.post('/a2a', (req, res) => { res.json({ protocol: 'A2A', status: 'operational', message: 'Agent-to-Agent communication endpoint' }); });
app.post('/mcp', (req, res) => { res.json({ protocol: 'MCP', status: 'operational', message: 'Model Context Protocol endpoint' }); });
app.post('/x402', (req, res) => { res.status(402).json({ protocol: 'x402', message: 'Payment Required', payment_required: true, accepted_currencies: ['USDC', 'USDCx', 'ETH'], network: 'base', settlement_address: '0x7bEda57074AA917FF0993fb329E16C2c188baF08' }); });
app.post('/v1/market', (req, res) => { res.json({ capability: 'market_intelligence', status: 'operational', pricing: { model: 'per_request', amount: '0.15', currency: 'USDC', network: 'base' }, demo_data: { base_tvl: '$2.4B', top_dexs: ['Uniswap V3', 'Aerodrome', 'BaseSwap'], fear_greed_index: 65 } }); });
app.post('/v1/scripture-match', (req, res) => { res.json({ capability: 'biblical_defi_correlation', status: 'operational', scripture: { reference: 'Proverbs 21:5', text: 'The thoughts of the diligent tend only to plenteousness; but of every one that is hasty only to want.', correlation: 'Warns against hasty trading during volatility', confidence: 0.87 } }); });
app.post('/v1/churches', (req, res) => { res.json({ capability: 'church_database_access', status: 'coming_soon', authentication: 'OAuth2 required' }); });
app.post('/v1/streams', (req, res) => { res.json({ capability: 'superfluid_streaming', status: 'operational', superfluid_links: { app: 'https://app.superfluid.finance', console: 'https://console.superfluid.finance' } }); });
app.post('/v1/private', (req, res) => { res.json({ capability: 'privacy_transactions', status: 'coming_soon', privacy_tech: { zkp_language: 'Noir', protocol: 'veil.cash' } }); });
// ── Global error handler ──────────────────────────────────────────────────────
app.use(errorHandler);

// ── Start server ──────────────────────────────────────────────────────────────
app.listen(PORT, '0.0.0.0', () => {
console.log(`BibleFi BWTYA API running on port ${PORT}`);
console.log(`Base App ID: ${BASE_APP_ID}`);
});
console.log(`🚀 BibleFi BWTYA API v2.0.0 running on port ${PORT}`);
console.log(` Network: Base (chainId 8453)`);
console.log(` Supabase: ${process.env.SUPABASE_URL ? '✅ connected' : '⚠️ not configured'}`);
console.log(` OpenAI: ${process.env.OPENAI_API_KEY ? '✅ connected' : '⚠️ not configured'}`);
console.log(` Viem: ${process.env.VIEM_PRIVATE_KEY ? '✅ configured' : '⚠️ not configured'}`);

// Start background jobs
registerJobs();
});
Loading