Skip to content
Open
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
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ This hackathon by Locus provided the exact infrastructure to solve this. So, I b
1. Contributors search for open bounties.
2. They open a PR linking the issue (e.g., `Fixes #123`, `Closes #123`). Bountic detects `pull_request.opened` and marks the PR as competing.
3. **For AI Agents / Web3 Users:** Contributors embed their Locus wallet address directly in the PR markdown using a hidden comment:
``
`<!-- bountic-address: 0xYourWalletAddress -->`

The legacy `<!-- locus-wallet: 0xYourWalletAddress -->` tag is also supported for existing contributors.

### 3. Merge & Settle (Payout)
1. The maintainer merges the winning PR (`pull_request.closed`).
Expand Down Expand Up @@ -136,4 +138,4 @@ LOCUS_WEBHOOK_SECRET=
**3. Start the Development Server**
```bash
npm run dev
```
```
7 changes: 3 additions & 4 deletions lib/bounty/services/payout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { getLocusServerClient } from "@/lib/clients/locus/server";
import { getSupabaseServiceClient } from "@/lib/clients/supabase/server";
import { getSupabaseServerEnv } from "@/lib/env/server";
import { getGithubInstallationClient, getGithubRepoInstallationId } from "@/lib/clients/github/server";

const BOUNTIC_ADDRESS_REGEX = /<!--\s*bountic-address:\s*(0x[a-fA-F0-9]{40})\s*-->/i;
import { BOUNTIC_ADDRESS_TAG_REGEX, LOCUS_WALLET_TAG_REGEX } from "@/lib/constants/bounty";

export type PayoutResult = {
transactionId: string;
Expand All @@ -17,7 +16,7 @@ export type PayoutResult = {

function extractWalletFromPrBody(prBody: string | null): string | null {
if (!prBody) return null;
const match = BOUNTIC_ADDRESS_REGEX.exec(prBody);
const match = BOUNTIC_ADDRESS_TAG_REGEX.exec(prBody) ?? LOCUS_WALLET_TAG_REGEX.exec(prBody);
return match ? match[1] : null;
}

Expand Down Expand Up @@ -173,4 +172,4 @@ export async function resolveAndPayout(params: {
amount: params.amount,
issueId: params.issueId,
});
}
}
9 changes: 5 additions & 4 deletions lib/bounty/services/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import "server-only";

import { getSupabaseServiceClient } from "@/lib/clients/supabase/server";

const LOCUS_WALLET_REGEX = /<!--\s*locus-wallet:\s*(0x[a-fA-F0-9]{40})\s*-->/i;
import { BOUNTIC_ADDRESS_TAG_REGEX, LOCUS_WALLET_TAG_REGEX } from "@/lib/constants/bounty";

export async function resolveWalletAddress(params: {
prDescription: string | null;
prAuthorUsername: string;
}): Promise<string | null> {
if (params.prDescription) {
const walletMatch = LOCUS_WALLET_REGEX.exec(params.prDescription);
const walletMatch =
BOUNTIC_ADDRESS_TAG_REGEX.exec(params.prDescription) ??
LOCUS_WALLET_TAG_REGEX.exec(params.prDescription);

if (walletMatch) {
return walletMatch[1];
Expand All @@ -28,4 +29,4 @@ export async function resolveWalletAddress(params: {
}

return null;
}
}
3 changes: 3 additions & 0 deletions lib/constants/bounty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ export const BOUNTY_ISSUE_ID_REGEX =

export const LOCUS_WALLET_TAG_REGEX =
/<!--\s*locus-wallet:\s*(0x[a-fA-F0-9]{40})\s*-->/i;

export const BOUNTIC_ADDRESS_TAG_REGEX =
/<!--\s*bountic-address:\s*(0x[a-fA-F0-9]{40})\s*-->/i;