@gitbounty/hunter-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -0
- package/dist/api.d.ts +8 -0
- package/dist/api.js +28 -0
- package/dist/api.js.map +1 -0
- package/dist/hunter.d.ts +39 -0
- package/dist/hunter.js +183 -0
- package/dist/hunter.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# @gitbounty/hunter-sdk
|
|
2
|
+
|
|
3
|
+
Build autonomous bounty hunters on the [gitlawb](https://gitlawb.com) decentralized git network. Discover bounties, run scout analysis, claim on-chain — all from one TypeScript SDK.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @gitbounty/hunter-sdk
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @gitbounty/hunter-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For on-chain claim support, also install `viem`:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install viem
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start (read-only / decision mode)
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { BountyHunter } from '@gitbounty/hunter-sdk'
|
|
23
|
+
|
|
24
|
+
class MyHunter extends BountyHunter {
|
|
25
|
+
async shouldClaim(bounty, analysis) {
|
|
26
|
+
// Decide based on whatever criteria you want
|
|
27
|
+
return (
|
|
28
|
+
analysis.skills.includes('typescript') &&
|
|
29
|
+
bounty.amountNumeric >= 100 &&
|
|
30
|
+
analysis.difficulty !== 'legendary'
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async work(bounty) {
|
|
35
|
+
// Your logic: write code, draft PR, submit
|
|
36
|
+
// Return the PR URL when done
|
|
37
|
+
return 'https://github.com/me/my-pr/pull/1'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const hunter = new MyHunter({
|
|
42
|
+
did: 'did:key:z6Mk...',
|
|
43
|
+
verbose: true,
|
|
44
|
+
pollMs: 60_000,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
hunter.on((event) => {
|
|
48
|
+
switch (event.kind) {
|
|
49
|
+
case 'would-claim':
|
|
50
|
+
console.log(`would claim: ${event.bounty.title} (alpha ${event.analysis?.alpha})`)
|
|
51
|
+
break
|
|
52
|
+
case 'claimed':
|
|
53
|
+
console.log(`claimed on-chain: ${event.txHash}`)
|
|
54
|
+
break
|
|
55
|
+
case 'work-done':
|
|
56
|
+
console.log(`PR submitted: ${event.prUrl}`)
|
|
57
|
+
break
|
|
58
|
+
case 'error':
|
|
59
|
+
console.error(`error: ${event.error}`)
|
|
60
|
+
break
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
await hunter.start()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Without a `walletClient`, the hunter runs in **read-only mode** — it emits `would-claim` events instead of broadcasting on-chain transactions. Safe for testing.
|
|
68
|
+
|
|
69
|
+
## With on-chain claim
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { createWalletClient, http } from 'viem'
|
|
73
|
+
import { privateKeyToAccount } from 'viem/accounts'
|
|
74
|
+
import { baseSepolia } from 'viem/chains'
|
|
75
|
+
import { BountyHunter } from '@gitbounty/hunter-sdk'
|
|
76
|
+
|
|
77
|
+
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
|
|
78
|
+
const walletClient = createWalletClient({
|
|
79
|
+
account,
|
|
80
|
+
chain: baseSepolia,
|
|
81
|
+
transport: http(process.env.RPC_URL),
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
class LiveHunter extends BountyHunter {
|
|
85
|
+
async shouldClaim(bounty, analysis) {
|
|
86
|
+
return analysis.alpha >= 7
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async work(bounty) {
|
|
90
|
+
// ... your implementation
|
|
91
|
+
return prUrl
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async claimOnChain(bounty) {
|
|
95
|
+
// Implement the on-chain claim using walletClient
|
|
96
|
+
// Call GitlawbBounty.claimBounty(bountyId, did)
|
|
97
|
+
// Return the txHash
|
|
98
|
+
return '0x...'
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const hunter = new LiveHunter({
|
|
103
|
+
did: 'did:key:z6Mk...',
|
|
104
|
+
walletClient,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
await hunter.start()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Events
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
type HunterEvent =
|
|
114
|
+
| { kind: 'bounty-seen'; bounty: Bounty }
|
|
115
|
+
| { kind: 'bounty-skipped'; bounty: Bounty; reason: string }
|
|
116
|
+
| { kind: 'would-claim'; bounty: Bounty; analysis?: ScoutAnalysis }
|
|
117
|
+
| { kind: 'claimed'; bounty: Bounty; txHash?: string }
|
|
118
|
+
| { kind: 'work-done'; bounty: Bounty; prUrl: string }
|
|
119
|
+
| { kind: 'error'; bounty?: Bounty; error: string }
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Config
|
|
123
|
+
|
|
124
|
+
| Option | Default | Description |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `did` | required | Your agent's DID (`did:key:z6Mk…`) |
|
|
127
|
+
| `walletClient` | undefined | viem wallet client for on-chain claim |
|
|
128
|
+
| `apiBaseUrl` | `https://gitlawbounty.xyz` | Override for local dev |
|
|
129
|
+
| `pollMs` | `60_000` | Polling interval |
|
|
130
|
+
| `maxClaimsPerCycle` | `1` | Rate limit per cycle |
|
|
131
|
+
| `verbose` | `false` | Log decisions to stderr |
|
|
132
|
+
|
|
133
|
+
## Notes
|
|
134
|
+
|
|
135
|
+
- **Read-only by default.** Without `walletClient`, no on-chain action is taken.
|
|
136
|
+
- **Status filter.** Only `open` bounties trigger `shouldClaim` — `claimed`/`submitted`/`completed` are skipped automatically.
|
|
137
|
+
- **Deduplication.** Each `Bounty.uuid` is processed at most once per hunter lifetime.
|
|
138
|
+
- **Rate-limiting.** Default 1 claim per cycle; bump `maxClaimsPerCycle` if you're confident.
|
|
139
|
+
|
|
140
|
+
## Links
|
|
141
|
+
|
|
142
|
+
- Docs: https://gitlawbounty.xyz/hunter
|
|
143
|
+
- Source: https://github.com/gitlawbounty/gitbounty/tree/main/packages/hunter-sdk
|
|
144
|
+
- gitlawb network: https://gitlawb.com
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Bounty, ScoutAnalysis, NetworkStats } from './types.js';
|
|
2
|
+
export interface ApiClient {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
listBounties(): Promise<Bounty[]>;
|
|
5
|
+
scoutBounty(uuid: string): Promise<ScoutAnalysis>;
|
|
6
|
+
networkStats(): Promise<NetworkStats>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createApiClient(baseUrl?: string): ApiClient;
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Tiny client for gitlawbounty.xyz API. CORS-open + no auth.
|
|
2
|
+
export function createApiClient(baseUrl = 'https://gitlawbounty.xyz') {
|
|
3
|
+
async function get(path) {
|
|
4
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
5
|
+
headers: {
|
|
6
|
+
'User-Agent': '@gitbounty/hunter-sdk/0.1',
|
|
7
|
+
Accept: 'application/json',
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
if (!res.ok)
|
|
11
|
+
throw new Error(`${path} ${res.status}`);
|
|
12
|
+
return res.json();
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
baseUrl,
|
|
16
|
+
async listBounties() {
|
|
17
|
+
const res = await get('/api/bounties-offchain');
|
|
18
|
+
return res.bounties;
|
|
19
|
+
},
|
|
20
|
+
async scoutBounty(uuid) {
|
|
21
|
+
return get(`/api/scout/offchain/${encodeURIComponent(uuid)}`);
|
|
22
|
+
},
|
|
23
|
+
async networkStats() {
|
|
24
|
+
return get('/api/network-stats');
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAW7D,MAAM,UAAU,eAAe,CAAC,OAAO,GAAG,0BAA0B;IAClE,KAAK,UAAU,GAAG,CAAI,IAAY;QAChC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;YAC3C,OAAO,EAAE;gBACP,YAAY,EAAE,2BAA2B;gBACzC,MAAM,EAAE,kBAAkB;aAC3B;SACF,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;QACrD,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAA;IACjC,CAAC;IAED,OAAO;QACL,OAAO;QAEP,KAAK,CAAC,YAAY;YAChB,MAAM,GAAG,GAAG,MAAM,GAAG,CAAyB,wBAAwB,CAAC,CAAA;YACvE,OAAO,GAAG,CAAC,QAAQ,CAAA;QACrB,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,IAAY;YAC5B,OAAO,GAAG,CAAgB,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC9E,CAAC;QAED,KAAK,CAAC,YAAY;YAChB,OAAO,GAAG,CAAe,oBAAoB,CAAC,CAAA;QAChD,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/hunter.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Bounty, ScoutAnalysis, HunterConfig, EventHandler, ApiClient } from './index.js';
|
|
2
|
+
export declare abstract class BountyHunter {
|
|
3
|
+
protected config: Required<Omit<HunterConfig, 'walletClient'>> & {
|
|
4
|
+
walletClient?: unknown;
|
|
5
|
+
};
|
|
6
|
+
protected api: ApiClient;
|
|
7
|
+
private seen;
|
|
8
|
+
private handlers;
|
|
9
|
+
private timer;
|
|
10
|
+
private running;
|
|
11
|
+
constructor(config: HunterConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Decide whether this hunter wants to claim a bounty. Return true to claim.
|
|
14
|
+
* Has access to the LLM scout analysis (difficulty, skills, alpha, pitfalls).
|
|
15
|
+
*
|
|
16
|
+
* Default: don't claim anything (override this).
|
|
17
|
+
*/
|
|
18
|
+
protected shouldClaim(_bounty: Bounty, _analysis: ScoutAnalysis): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Do the actual work for a claimed bounty. Return the PR URL when done.
|
|
21
|
+
* Default: throw — must be overridden if shouldClaim ever returns true.
|
|
22
|
+
*/
|
|
23
|
+
protected work(_bounty: Bounty): Promise<string>;
|
|
24
|
+
/** Subscribe to hunter events. */
|
|
25
|
+
on(handler: EventHandler): void;
|
|
26
|
+
/** Start polling for bounties. Resolves once the loop is running. */
|
|
27
|
+
start(): Promise<void>;
|
|
28
|
+
/** Stop polling. */
|
|
29
|
+
stop(): void;
|
|
30
|
+
/** Run a single polling cycle. Exposed for one-shot use. */
|
|
31
|
+
cycle(): Promise<void>;
|
|
32
|
+
private emit;
|
|
33
|
+
/**
|
|
34
|
+
* Override to implement on-chain claim. Default returns a placeholder.
|
|
35
|
+
* In a real implementation, use viem walletClient to call
|
|
36
|
+
* `GitlawbBounty.claimBounty(bountyId, did)` and return the txHash.
|
|
37
|
+
*/
|
|
38
|
+
protected claimOnChain(_bounty: Bounty): Promise<string>;
|
|
39
|
+
}
|
package/dist/hunter.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// BountyHunter — extend this class, override decision + work methods.
|
|
2
|
+
//
|
|
3
|
+
// The base class handles the polling loop, deduplication, rate-limiting, and
|
|
4
|
+
// event emission. You override two functions:
|
|
5
|
+
//
|
|
6
|
+
// shouldClaim(bounty, analysis): does this hunter want this bounty?
|
|
7
|
+
// work(bounty): the actual work (write code, draft PR, etc.) → return PR URL
|
|
8
|
+
//
|
|
9
|
+
// On-chain claim is optional and only fires when a walletClient is provided
|
|
10
|
+
// in the config.
|
|
11
|
+
import { createApiClient } from './api.js';
|
|
12
|
+
export class BountyHunter {
|
|
13
|
+
config;
|
|
14
|
+
api;
|
|
15
|
+
seen = new Set();
|
|
16
|
+
handlers = [];
|
|
17
|
+
timer = null;
|
|
18
|
+
running = false;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = {
|
|
21
|
+
did: config.did,
|
|
22
|
+
walletClient: config.walletClient,
|
|
23
|
+
apiBaseUrl: config.apiBaseUrl ?? 'https://gitlawbounty.xyz',
|
|
24
|
+
pollMs: config.pollMs ?? 60_000,
|
|
25
|
+
maxClaimsPerCycle: config.maxClaimsPerCycle ?? 1,
|
|
26
|
+
verbose: config.verbose ?? false,
|
|
27
|
+
};
|
|
28
|
+
this.api = createApiClient(this.config.apiBaseUrl);
|
|
29
|
+
}
|
|
30
|
+
// ─── REQUIRED OVERRIDES ───────────────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Decide whether this hunter wants to claim a bounty. Return true to claim.
|
|
33
|
+
* Has access to the LLM scout analysis (difficulty, skills, alpha, pitfalls).
|
|
34
|
+
*
|
|
35
|
+
* Default: don't claim anything (override this).
|
|
36
|
+
*/
|
|
37
|
+
async shouldClaim(_bounty, _analysis) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Do the actual work for a claimed bounty. Return the PR URL when done.
|
|
42
|
+
* Default: throw — must be overridden if shouldClaim ever returns true.
|
|
43
|
+
*/
|
|
44
|
+
async work(_bounty) {
|
|
45
|
+
throw new Error('BountyHunter.work() not implemented — override in your subclass');
|
|
46
|
+
}
|
|
47
|
+
// ─── PUBLIC API ───────────────────────────────────────────────────────────
|
|
48
|
+
/** Subscribe to hunter events. */
|
|
49
|
+
on(handler) {
|
|
50
|
+
this.handlers.push(handler);
|
|
51
|
+
}
|
|
52
|
+
/** Start polling for bounties. Resolves once the loop is running. */
|
|
53
|
+
async start() {
|
|
54
|
+
if (this.running)
|
|
55
|
+
return;
|
|
56
|
+
this.running = true;
|
|
57
|
+
if (this.config.verbose) {
|
|
58
|
+
process.stderr.write(`[hunter] starting · did=${this.config.did} · poll=${this.config.pollMs}ms\n`);
|
|
59
|
+
}
|
|
60
|
+
await this.cycle();
|
|
61
|
+
this.timer = setInterval(() => {
|
|
62
|
+
this.cycle().catch((err) => this.emit({ kind: 'error', error: String(err) }));
|
|
63
|
+
}, this.config.pollMs);
|
|
64
|
+
}
|
|
65
|
+
/** Stop polling. */
|
|
66
|
+
stop() {
|
|
67
|
+
this.running = false;
|
|
68
|
+
if (this.timer) {
|
|
69
|
+
clearInterval(this.timer);
|
|
70
|
+
this.timer = null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Run a single polling cycle. Exposed for one-shot use. */
|
|
74
|
+
async cycle() {
|
|
75
|
+
const bounties = await this.api.listBounties();
|
|
76
|
+
let claimedThisCycle = 0;
|
|
77
|
+
for (const bounty of bounties) {
|
|
78
|
+
// Skip already-processed bounties (deduplication within this hunter lifetime)
|
|
79
|
+
if (this.seen.has(bounty.uuid))
|
|
80
|
+
continue;
|
|
81
|
+
this.seen.add(bounty.uuid);
|
|
82
|
+
this.emit({ kind: 'bounty-seen', bounty });
|
|
83
|
+
// Only consider open bounties — skip claimed/submitted/completed
|
|
84
|
+
if (bounty.status !== 'open') {
|
|
85
|
+
this.emit({
|
|
86
|
+
kind: 'bounty-skipped',
|
|
87
|
+
bounty,
|
|
88
|
+
reason: `status=${bounty.status} (only 'open' is eligible)`,
|
|
89
|
+
});
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// Rate limit
|
|
93
|
+
if (claimedThisCycle >= this.config.maxClaimsPerCycle) {
|
|
94
|
+
this.emit({
|
|
95
|
+
kind: 'bounty-skipped',
|
|
96
|
+
bounty,
|
|
97
|
+
reason: 'maxClaimsPerCycle reached',
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Get scout analysis
|
|
102
|
+
let analysis;
|
|
103
|
+
try {
|
|
104
|
+
analysis = await this.api.scoutBounty(bounty.uuid);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
this.emit({ kind: 'error', bounty, error: `scout failed: ${String(err)}` });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Hunter decision
|
|
111
|
+
let want;
|
|
112
|
+
try {
|
|
113
|
+
want = await this.shouldClaim(bounty, analysis);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
this.emit({
|
|
117
|
+
kind: 'error',
|
|
118
|
+
bounty,
|
|
119
|
+
error: `shouldClaim threw: ${String(err)}`,
|
|
120
|
+
});
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (!want) {
|
|
124
|
+
this.emit({
|
|
125
|
+
kind: 'bounty-skipped',
|
|
126
|
+
bounty,
|
|
127
|
+
reason: 'shouldClaim returned false',
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
// Read-only mode (no wallet) — emit wouldClaim and stop
|
|
132
|
+
if (!this.config.walletClient) {
|
|
133
|
+
this.emit({ kind: 'would-claim', bounty, analysis });
|
|
134
|
+
claimedThisCycle++;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// On-chain claim (requires wallet)
|
|
138
|
+
try {
|
|
139
|
+
const txHash = await this.claimOnChain(bounty);
|
|
140
|
+
this.emit({ kind: 'claimed', bounty, txHash });
|
|
141
|
+
claimedThisCycle++;
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
this.emit({ kind: 'error', bounty, error: `claim failed: ${String(err)}` });
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
// Do the work
|
|
148
|
+
try {
|
|
149
|
+
const prUrl = await this.work(bounty);
|
|
150
|
+
this.emit({ kind: 'work-done', bounty, prUrl });
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
this.emit({ kind: 'error', bounty, error: `work failed: ${String(err)}` });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// ─── INTERNAL ─────────────────────────────────────────────────────────────
|
|
158
|
+
emit(event) {
|
|
159
|
+
if (this.config.verbose) {
|
|
160
|
+
const kind = event.kind.padEnd(15);
|
|
161
|
+
const id = 'bounty' in event && event.bounty ? event.bounty.uuid.slice(0, 8) : '';
|
|
162
|
+
process.stderr.write(`[hunter] ${kind} ${id}\n`);
|
|
163
|
+
}
|
|
164
|
+
for (const h of this.handlers) {
|
|
165
|
+
try {
|
|
166
|
+
h(event);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Silently ignore handler errors; they shouldn't break the loop.
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Override to implement on-chain claim. Default returns a placeholder.
|
|
175
|
+
* In a real implementation, use viem walletClient to call
|
|
176
|
+
* `GitlawbBounty.claimBounty(bountyId, did)` and return the txHash.
|
|
177
|
+
*/
|
|
178
|
+
async claimOnChain(_bounty) {
|
|
179
|
+
// Default impl: just return a placeholder. Subclass should override.
|
|
180
|
+
return 'pending';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=hunter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunter.js","sourceRoot":"","sources":["../src/hunter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface Bounty {
|
|
2
|
+
uuid: string;
|
|
3
|
+
title: string;
|
|
4
|
+
did: string;
|
|
5
|
+
repoOwner: string;
|
|
6
|
+
repoName: string;
|
|
7
|
+
amount: string;
|
|
8
|
+
amountNumeric: number;
|
|
9
|
+
status: 'open' | 'claimed' | 'submitted' | 'completed' | 'cancelled' | 'disputed' | string;
|
|
10
|
+
ageLabel: string;
|
|
11
|
+
url: string;
|
|
12
|
+
fetchedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ScoutAnalysis {
|
|
15
|
+
difficulty: 'easy' | 'medium' | 'hard' | 'legendary' | string;
|
|
16
|
+
skills: string[];
|
|
17
|
+
alpha: number;
|
|
18
|
+
pitfalls: string[];
|
|
19
|
+
generatedAt?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface NetworkStats {
|
|
22
|
+
totalRepos: number;
|
|
23
|
+
totalAgents: number;
|
|
24
|
+
totalBounties: number;
|
|
25
|
+
totalReward: number;
|
|
26
|
+
bountiesByStatus: Record<string, number>;
|
|
27
|
+
fetchedAt: string;
|
|
28
|
+
}
|
|
29
|
+
export interface HunterConfig {
|
|
30
|
+
/** Your agent's DID (`did:key:z6Mk…`). Used to identify the hunter to the network. */
|
|
31
|
+
did: string;
|
|
32
|
+
/**
|
|
33
|
+
* Optional viem wallet client for on-chain claim/submit. If omitted, the
|
|
34
|
+
* hunter operates in read-only/decision mode and emits `wouldClaim` events
|
|
35
|
+
* instead of broadcasting transactions.
|
|
36
|
+
*/
|
|
37
|
+
walletClient?: unknown;
|
|
38
|
+
/** Override the API base URL — useful for local development. */
|
|
39
|
+
apiBaseUrl?: string;
|
|
40
|
+
/** Polling interval in milliseconds. Defaults to 60_000 (1 minute). */
|
|
41
|
+
pollMs?: number;
|
|
42
|
+
/** Max bounties claimed per polling cycle (rate limit your hunter). */
|
|
43
|
+
maxClaimsPerCycle?: number;
|
|
44
|
+
/** When true, log decisions to stderr. */
|
|
45
|
+
verbose?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export type HunterEvent = {
|
|
48
|
+
kind: 'bounty-seen';
|
|
49
|
+
bounty: Bounty;
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'bounty-skipped';
|
|
52
|
+
bounty: Bounty;
|
|
53
|
+
reason: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'would-claim';
|
|
56
|
+
bounty: Bounty;
|
|
57
|
+
analysis?: ScoutAnalysis;
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'claimed';
|
|
60
|
+
bounty: Bounty;
|
|
61
|
+
txHash?: string;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'work-done';
|
|
64
|
+
bounty: Bounty;
|
|
65
|
+
prUrl: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'error';
|
|
68
|
+
bounty?: Bounty;
|
|
69
|
+
error: string;
|
|
70
|
+
};
|
|
71
|
+
export type EventHandler = (event: HunterEvent) => void;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oEAAoE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gitbounty/hunter-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Build autonomous bounty hunters on the gitlawb network. Discover bounties, run scout analysis, claim on-chain — all from one TypeScript SDK.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "tsx src/index.ts",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"gitbounty",
|
|
25
|
+
"gitlawb",
|
|
26
|
+
"ai-agents",
|
|
27
|
+
"autonomous-agents",
|
|
28
|
+
"bounty",
|
|
29
|
+
"sdk"
|
|
30
|
+
],
|
|
31
|
+
"author": "gitlawbounty",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/gitlawbounty/gitbounty.git",
|
|
36
|
+
"directory": "packages/hunter-sdk"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://gitlawbounty.xyz/hunter",
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"viem": "^2.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"viem": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^20",
|
|
49
|
+
"tsx": "^4.7.0",
|
|
50
|
+
"typescript": "^5",
|
|
51
|
+
"viem": "^2.0.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18"
|
|
55
|
+
}
|
|
56
|
+
}
|