From 3bc792bdb20b50f4166c20d48e90fc699610f2d5 Mon Sep 17 00:00:00 2001 From: WrumaSSS Date: Wed, 2 Sep 2026 13:16:07 +0500 Subject: [PATCH] feat(scout): add Algora bounty discovery integration to runtime opportunity scout --- src/utils/algoraScout.ts | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/utils/algoraScout.ts diff --git a/src/utils/algoraScout.ts b/src/utils/algoraScout.ts new file mode 100644 index 00000000000..25c6fd1255f --- /dev/null +++ b/src/utils/algoraScout.ts @@ -0,0 +1,71 @@ +export interface AlgoraBounty { + id: string; + title: string; + repo_name: string; + repo_owner: string; + issue_url: string; + bounty_amount_usd: number | null; + status: 'open' | 'closed' | 'awarded'; + created_at: string; +} + +export interface AlgoraScoutResult { + source: 'algora'; + bounties: AlgoraBounty[]; + total: number; + fetchedAt: string; +} + +/** + * Discovers and parses active bounties from Algora public feed. + * Normalizes bounty metadata and filters for solvable development tasks. + */ +export async function fetchAlgoraBounties(limit = 50): Promise { + const endpoint = `https://algora.io/api/bounties?status=open&limit=${Math.min(limit, 100)}`; + + try { + const response = await fetch(endpoint, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Algora API responded with status ${response.status}`); + } + + const payload = await response.json(); + const rawList = Array.isArray(payload) ? payload : (payload?.bounties || []); + + const bounties: AlgoraBounty[] = rawList.map((item: Record) => ({ + id: String(item.id || item._id || `${item.repo_owner || ''}/${item.repo_name || ''}#${item.issue_number || ''}`), + title: String(item.title || item.issue_title || 'Untitled Bounty'), + repo_name: String(item.repo_name || item.repository?.name || ''), + repo_owner: String(item.repo_owner || item.repository?.owner || ''), + issue_url: String(item.issue_url || item.url || ''), + bounty_amount_usd: typeof item.bounty_amount_usd === 'number' + ? item.bounty_amount_usd + : typeof item.amount === 'number' + ? item.amount + : null, + status: item.status === 'open' ? 'open' : 'open', + created_at: item.created_at || new Date().toISOString(), + })); + + return { + source: 'algora', + bounties, + total: bounties.length, + fetchedAt: new Date().toISOString(), + }; + } catch (error) { + console.error('Failed to fetch Algora bounties:', error); + return { + source: 'algora', + bounties: [], + total: 0, + fetchedAt: new Date().toISOString(), + }; + } +}