arcbounty-agent-sdk 0.1.0 → 0.3.1
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 +136 -2
- package/dist/index.d.mts +232 -11
- package/dist/index.d.ts +232 -11
- package/dist/index.js +392 -143
- package/dist/index.mjs +383 -139
- package/package.json +11 -3
- package/.env.example +0 -13
- package/examples/demo-agent.ts +0 -94
- package/src/ArcBountyAgent.ts +0 -645
- package/src/abi.ts +0 -386
- package/src/constants.ts +0 -20
- package/src/index.ts +0 -21
- package/src/ipfs.ts +0 -80
- package/src/metadata.ts +0 -69
- package/src/types.ts +0 -105
- package/tsconfig.json +0 -13
package/src/abi.ts
DELETED
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
// Canonical ABI for BountyAdapter V2 (humanOnly + dispute evidence).
|
|
2
|
-
// Mirrors contracts/src/BountyAdapter.sol and frontend/lib/contracts.ts.
|
|
3
|
-
|
|
4
|
-
const BOUNTY_META_TUPLE = {
|
|
5
|
-
name: "",
|
|
6
|
-
type: "tuple" as const,
|
|
7
|
-
components: [
|
|
8
|
-
{ name: "jobId", type: "uint256" },
|
|
9
|
-
{ name: "poster", type: "address" },
|
|
10
|
-
{ name: "reward", type: "uint256" },
|
|
11
|
-
{ name: "deadline", type: "uint256" },
|
|
12
|
-
{ name: "ipfsDescHash", type: "string" },
|
|
13
|
-
{ name: "category", type: "string" },
|
|
14
|
-
{ name: "tags", type: "string[]" },
|
|
15
|
-
{ name: "agentId", type: "uint256" },
|
|
16
|
-
{ name: "agentOnly", type: "bool" },
|
|
17
|
-
{ name: "humanOnly", type: "bool" },
|
|
18
|
-
{ name: "whitelistedProvider", type: "address" },
|
|
19
|
-
{ name: "assignedProvider", type: "address" },
|
|
20
|
-
{ name: "submittedResultHash", type: "string" },
|
|
21
|
-
{ name: "submittedAt", type: "uint256" },
|
|
22
|
-
{ name: "isTaken", type: "bool" },
|
|
23
|
-
{ name: "rejectedAt", type: "uint256" },
|
|
24
|
-
{ name: "rejectionReasonHash", type: "string" },
|
|
25
|
-
{ name: "inDispute", type: "bool" },
|
|
26
|
-
{ name: "resolved", type: "bool" },
|
|
27
|
-
{ name: "disputeInitiator", type: "address" },
|
|
28
|
-
{ name: "disputeRaisedAt", type: "uint256" },
|
|
29
|
-
{ name: "disputeReasonHash", type: "string" },
|
|
30
|
-
{ name: "disputeResponseHash", type: "string" },
|
|
31
|
-
{ name: "disputeRulingHash", type: "string" },
|
|
32
|
-
],
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
|
-
export const BOUNTY_ADAPTER_ABI = [
|
|
36
|
-
// ── Write ──
|
|
37
|
-
{
|
|
38
|
-
name: "createBounty",
|
|
39
|
-
type: "function" as const,
|
|
40
|
-
stateMutability: "nonpayable" as const,
|
|
41
|
-
inputs: [{
|
|
42
|
-
name: "p",
|
|
43
|
-
type: "tuple",
|
|
44
|
-
components: [
|
|
45
|
-
{ name: "provider", type: "address" },
|
|
46
|
-
{ name: "reward", type: "uint256" },
|
|
47
|
-
{ name: "deadline", type: "uint256" },
|
|
48
|
-
{ name: "ipfsDescHash", type: "string" },
|
|
49
|
-
{ name: "category", type: "string" },
|
|
50
|
-
{ name: "tags", type: "string[]" },
|
|
51
|
-
{ name: "agentOnly", type: "bool" },
|
|
52
|
-
{ name: "humanOnly", type: "bool" },
|
|
53
|
-
],
|
|
54
|
-
}],
|
|
55
|
-
outputs: [{ name: "jobId", type: "uint256" }],
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: "takeBounty",
|
|
59
|
-
type: "function" as const,
|
|
60
|
-
stateMutability: "nonpayable" as const,
|
|
61
|
-
inputs: [
|
|
62
|
-
{ name: "jobId", type: "uint256" },
|
|
63
|
-
{ name: "agentId", type: "uint256" },
|
|
64
|
-
],
|
|
65
|
-
outputs: [],
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: "submitWork",
|
|
69
|
-
type: "function" as const,
|
|
70
|
-
stateMutability: "nonpayable" as const,
|
|
71
|
-
inputs: [
|
|
72
|
-
{ name: "jobId", type: "uint256" },
|
|
73
|
-
{ name: "ipfsResultHash", type: "string" },
|
|
74
|
-
],
|
|
75
|
-
outputs: [],
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: "approveBounty",
|
|
79
|
-
type: "function" as const,
|
|
80
|
-
stateMutability: "nonpayable" as const,
|
|
81
|
-
inputs: [
|
|
82
|
-
{ name: "jobId", type: "uint256" },
|
|
83
|
-
{ name: "reputationScore", type: "uint8" },
|
|
84
|
-
],
|
|
85
|
-
outputs: [],
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "autoApprove",
|
|
89
|
-
type: "function" as const,
|
|
90
|
-
stateMutability: "nonpayable" as const,
|
|
91
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
92
|
-
outputs: [],
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: "rejectBounty",
|
|
96
|
-
type: "function" as const,
|
|
97
|
-
stateMutability: "nonpayable" as const,
|
|
98
|
-
inputs: [
|
|
99
|
-
{ name: "jobId", type: "uint256" },
|
|
100
|
-
{ name: "ipfsReasonHash", type: "string" },
|
|
101
|
-
],
|
|
102
|
-
outputs: [],
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "challengeRejection",
|
|
106
|
-
type: "function" as const,
|
|
107
|
-
stateMutability: "nonpayable" as const,
|
|
108
|
-
inputs: [
|
|
109
|
-
{ name: "jobId", type: "uint256" },
|
|
110
|
-
{ name: "ipfsReasonHash", type: "string" },
|
|
111
|
-
],
|
|
112
|
-
outputs: [],
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
name: "finalizeRejection",
|
|
116
|
-
type: "function" as const,
|
|
117
|
-
stateMutability: "nonpayable" as const,
|
|
118
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
119
|
-
outputs: [],
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: "cancelBounty",
|
|
123
|
-
type: "function" as const,
|
|
124
|
-
stateMutability: "nonpayable" as const,
|
|
125
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
126
|
-
outputs: [],
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: "expireBounty",
|
|
130
|
-
type: "function" as const,
|
|
131
|
-
stateMutability: "nonpayable" as const,
|
|
132
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
133
|
-
outputs: [],
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: "disputeBounty",
|
|
137
|
-
type: "function" as const,
|
|
138
|
-
stateMutability: "nonpayable" as const,
|
|
139
|
-
inputs: [
|
|
140
|
-
{ name: "jobId", type: "uint256" },
|
|
141
|
-
{ name: "ipfsReasonHash", type: "string" },
|
|
142
|
-
],
|
|
143
|
-
outputs: [],
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: "respondToDispute",
|
|
147
|
-
type: "function" as const,
|
|
148
|
-
stateMutability: "nonpayable" as const,
|
|
149
|
-
inputs: [
|
|
150
|
-
{ name: "jobId", type: "uint256" },
|
|
151
|
-
{ name: "ipfsResponseHash", type: "string" },
|
|
152
|
-
],
|
|
153
|
-
outputs: [],
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
name: "resolveDispute",
|
|
157
|
-
type: "function" as const,
|
|
158
|
-
stateMutability: "nonpayable" as const,
|
|
159
|
-
inputs: [
|
|
160
|
-
{ name: "jobId", type: "uint256" },
|
|
161
|
-
{ name: "payProvider", type: "bool" },
|
|
162
|
-
{ name: "ipfsRulingHash", type: "string" },
|
|
163
|
-
{ name: "reputationPenalty", type: "uint8" },
|
|
164
|
-
],
|
|
165
|
-
outputs: [],
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
name: "claimDefaultRuling",
|
|
169
|
-
type: "function" as const,
|
|
170
|
-
stateMutability: "nonpayable" as const,
|
|
171
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
172
|
-
outputs: [],
|
|
173
|
-
},
|
|
174
|
-
// ── Read ──
|
|
175
|
-
{
|
|
176
|
-
name: "getOpenBounties",
|
|
177
|
-
type: "function" as const,
|
|
178
|
-
stateMutability: "view" as const,
|
|
179
|
-
inputs: [
|
|
180
|
-
{ name: "category", type: "string" },
|
|
181
|
-
{ name: "offset", type: "uint256" },
|
|
182
|
-
{ name: "limit", type: "uint256" },
|
|
183
|
-
],
|
|
184
|
-
outputs: [{ name: "result", type: "uint256[]" }],
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
name: "getBountyMeta",
|
|
188
|
-
type: "function" as const,
|
|
189
|
-
stateMutability: "view" as const,
|
|
190
|
-
inputs: [{ name: "jobId", type: "uint256" }],
|
|
191
|
-
outputs: [BOUNTY_META_TUPLE],
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
name: "getMyPostedBounties",
|
|
195
|
-
type: "function" as const,
|
|
196
|
-
stateMutability: "view" as const,
|
|
197
|
-
inputs: [{ name: "poster", type: "address" }],
|
|
198
|
-
outputs: [{ name: "", type: "uint256[]" }],
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
name: "getMyAssignedBounties",
|
|
202
|
-
type: "function" as const,
|
|
203
|
-
stateMutability: "view" as const,
|
|
204
|
-
inputs: [{ name: "provider", type: "address" }],
|
|
205
|
-
outputs: [{ name: "", type: "uint256[]" }],
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
name: "getAgentBounties",
|
|
209
|
-
type: "function" as const,
|
|
210
|
-
stateMutability: "view" as const,
|
|
211
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
212
|
-
outputs: [{ name: "", type: "uint256[]" }],
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: "APPROVAL_TIMEOUT",
|
|
216
|
-
type: "function" as const,
|
|
217
|
-
stateMutability: "view" as const,
|
|
218
|
-
inputs: [], outputs: [{ name: "", type: "uint256" }],
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
name: "getAgentReputation",
|
|
222
|
-
type: "function" as const,
|
|
223
|
-
stateMutability: "view" as const,
|
|
224
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
225
|
-
outputs: [{
|
|
226
|
-
name: "",
|
|
227
|
-
type: "tuple",
|
|
228
|
-
components: [
|
|
229
|
-
{ name: "averageScore", type: "uint256" },
|
|
230
|
-
{ name: "totalFeedbacks", type: "uint256" },
|
|
231
|
-
{ name: "totalJobs", type: "uint256" },
|
|
232
|
-
],
|
|
233
|
-
}],
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
name: "totalBounties",
|
|
237
|
-
type: "function" as const,
|
|
238
|
-
stateMutability: "view" as const,
|
|
239
|
-
inputs: [],
|
|
240
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
name: "arbitrator",
|
|
244
|
-
type: "function" as const,
|
|
245
|
-
stateMutability: "view" as const,
|
|
246
|
-
inputs: [],
|
|
247
|
-
outputs: [{ name: "", type: "address" }],
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
name: "DISPUTE_RESPONSE_WINDOW",
|
|
251
|
-
type: "function" as const,
|
|
252
|
-
stateMutability: "view" as const,
|
|
253
|
-
inputs: [],
|
|
254
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
name: "REJECTION_CHALLENGE_WINDOW",
|
|
258
|
-
type: "function" as const,
|
|
259
|
-
stateMutability: "view" as const,
|
|
260
|
-
inputs: [],
|
|
261
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
262
|
-
},
|
|
263
|
-
// ── Events ──
|
|
264
|
-
{
|
|
265
|
-
name: "BountyCreated",
|
|
266
|
-
type: "event" as const,
|
|
267
|
-
inputs: [
|
|
268
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
269
|
-
{ name: "poster", type: "address", indexed: true },
|
|
270
|
-
{ name: "reward", type: "uint256", indexed: false },
|
|
271
|
-
{ name: "category", type: "string", indexed: false },
|
|
272
|
-
{ name: "deadline", type: "uint256", indexed: false },
|
|
273
|
-
],
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
name: "BountyTaken",
|
|
277
|
-
type: "event" as const,
|
|
278
|
-
inputs: [
|
|
279
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
280
|
-
{ name: "provider", type: "address", indexed: true },
|
|
281
|
-
{ name: "agentId", type: "uint256", indexed: false },
|
|
282
|
-
],
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
name: "WorkSubmitted",
|
|
286
|
-
type: "event" as const,
|
|
287
|
-
inputs: [
|
|
288
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
289
|
-
{ name: "provider", type: "address", indexed: true },
|
|
290
|
-
{ name: "ipfsResultHash", type: "string", indexed: false },
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
name: "BountyCompleted",
|
|
295
|
-
type: "event" as const,
|
|
296
|
-
inputs: [
|
|
297
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
298
|
-
{ name: "agentId", type: "uint256", indexed: false },
|
|
299
|
-
{ name: "reputationScore", type: "uint256", indexed: false },
|
|
300
|
-
],
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
name: "DisputeRaised",
|
|
304
|
-
type: "event" as const,
|
|
305
|
-
inputs: [
|
|
306
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
307
|
-
{ name: "initiator", type: "address", indexed: true },
|
|
308
|
-
{ name: "reasonHash", type: "string", indexed: false },
|
|
309
|
-
],
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
name: "DisputeResponded",
|
|
313
|
-
type: "event" as const,
|
|
314
|
-
inputs: [
|
|
315
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
316
|
-
{ name: "responder", type: "address", indexed: true },
|
|
317
|
-
{ name: "responseHash", type: "string", indexed: false },
|
|
318
|
-
],
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
name: "DisputeResolved",
|
|
322
|
-
type: "event" as const,
|
|
323
|
-
inputs: [
|
|
324
|
-
{ name: "jobId", type: "uint256", indexed: true },
|
|
325
|
-
{ name: "payProvider", type: "bool", indexed: false },
|
|
326
|
-
{ name: "rulingHash", type: "string", indexed: false },
|
|
327
|
-
{ name: "defaultRuling", type: "bool", indexed: false },
|
|
328
|
-
],
|
|
329
|
-
},
|
|
330
|
-
] as const;
|
|
331
|
-
|
|
332
|
-
export const IDENTITY_REGISTRY_ABI = [
|
|
333
|
-
{
|
|
334
|
-
name: "register",
|
|
335
|
-
type: "function" as const,
|
|
336
|
-
stateMutability: "nonpayable" as const,
|
|
337
|
-
inputs: [{ name: "metadataURI", type: "string" }],
|
|
338
|
-
outputs: [{ name: "agentId", type: "uint256" }],
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
name: "ownerOf",
|
|
342
|
-
type: "function" as const,
|
|
343
|
-
stateMutability: "view" as const,
|
|
344
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
345
|
-
outputs: [{ name: "", type: "address" }],
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
name: "Transfer",
|
|
349
|
-
type: "event" as const,
|
|
350
|
-
inputs: [
|
|
351
|
-
{ name: "from", type: "address", indexed: true },
|
|
352
|
-
{ name: "to", type: "address", indexed: true },
|
|
353
|
-
{ name: "tokenId", type: "uint256", indexed: true },
|
|
354
|
-
],
|
|
355
|
-
},
|
|
356
|
-
] as const;
|
|
357
|
-
|
|
358
|
-
export const ERC20_ABI = [
|
|
359
|
-
{
|
|
360
|
-
name: "approve",
|
|
361
|
-
type: "function" as const,
|
|
362
|
-
stateMutability: "nonpayable" as const,
|
|
363
|
-
inputs: [
|
|
364
|
-
{ name: "spender", type: "address" },
|
|
365
|
-
{ name: "amount", type: "uint256" },
|
|
366
|
-
],
|
|
367
|
-
outputs: [{ name: "", type: "bool" }],
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
name: "allowance",
|
|
371
|
-
type: "function" as const,
|
|
372
|
-
stateMutability: "view" as const,
|
|
373
|
-
inputs: [
|
|
374
|
-
{ name: "owner", type: "address" },
|
|
375
|
-
{ name: "spender", type: "address" },
|
|
376
|
-
],
|
|
377
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
name: "balanceOf",
|
|
381
|
-
type: "function" as const,
|
|
382
|
-
stateMutability: "view" as const,
|
|
383
|
-
inputs: [{ name: "account", type: "address" }],
|
|
384
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
385
|
-
},
|
|
386
|
-
] as const;
|
package/src/constants.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { Address } from "viem";
|
|
2
|
-
|
|
3
|
-
export const ARC_TESTNET_RPC = "https://rpc.testnet.arc.network";
|
|
4
|
-
export const ARC_TESTNET_CHAIN_ID = 5_042_002;
|
|
5
|
-
|
|
6
|
-
export const CONTRACTS = {
|
|
7
|
-
AGENTIC_COMMERCE: "0x0747EEf0706327138c69792bF28Cd525089e4583" as Address,
|
|
8
|
-
IDENTITY_REGISTRY: "0x8004A818BFB912233c491871b3d84c89A494BD9e" as Address,
|
|
9
|
-
REPUTATION_REGISTRY: "0x8004B663056A597Dffe9eCcC1965A193B7388713" as Address,
|
|
10
|
-
USDC: "0x3600000000000000000000000000000000000000" as Address,
|
|
11
|
-
} as const;
|
|
12
|
-
|
|
13
|
-
export const USDC_DECIMALS = 6;
|
|
14
|
-
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" as Address;
|
|
15
|
-
|
|
16
|
-
export const IPFS_GATEWAYS = [
|
|
17
|
-
"https://gateway.pinata.cloud/ipfs/",
|
|
18
|
-
"https://ipfs.io/ipfs/",
|
|
19
|
-
"https://cloudflare-ipfs.com/ipfs/",
|
|
20
|
-
];
|
package/src/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export { ArcBountyAgent } from "./ArcBountyAgent.js";
|
|
2
|
-
export type {
|
|
3
|
-
ArcBountyAgentConfig,
|
|
4
|
-
BountyMeta,
|
|
5
|
-
ReputationScore,
|
|
6
|
-
OpenBountiesFilter,
|
|
7
|
-
CreateBountyOptions,
|
|
8
|
-
SubmitWorkOptions,
|
|
9
|
-
DisputeEvidenceOptions,
|
|
10
|
-
AgentInfo,
|
|
11
|
-
TxResult,
|
|
12
|
-
} from "./types.js";
|
|
13
|
-
export { CONTRACTS, ARC_TESTNET_RPC, ARC_TESTNET_CHAIN_ID } from "./constants.js";
|
|
14
|
-
export { BOUNTY_ADAPTER_ABI, IDENTITY_REGISTRY_ABI, ERC20_ABI } from "./abi.js";
|
|
15
|
-
export { pinText, fetchIpfsText, fetchIpfsJson, isPinningConfigured } from "./ipfs.js";
|
|
16
|
-
export {
|
|
17
|
-
pinAgentMetadata,
|
|
18
|
-
validateAgentMetadata,
|
|
19
|
-
type AgentMetadata,
|
|
20
|
-
type ArcBountySection,
|
|
21
|
-
} from "./metadata.js";
|
package/src/ipfs.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { IPFS_GATEWAYS } from "./constants.js";
|
|
2
|
-
|
|
3
|
-
function cidFromUri(uriOrCid: string): string {
|
|
4
|
-
return uriOrCid.replace(/^ipfs:\/\//, "");
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export async function fetchIpfsText(uriOrCid: string): Promise<string> {
|
|
8
|
-
const cid = cidFromUri(uriOrCid);
|
|
9
|
-
for (const gateway of IPFS_GATEWAYS) {
|
|
10
|
-
try {
|
|
11
|
-
const res = await fetch(`${gateway}${cid}`);
|
|
12
|
-
if (res.ok) return res.text();
|
|
13
|
-
} catch {
|
|
14
|
-
// try next gateway
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
throw new Error(`Failed to fetch IPFS content: ${uriOrCid}`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function fetchIpfsJson<T = unknown>(uriOrCid: string): Promise<T> {
|
|
21
|
-
const text = await fetchIpfsText(uriOrCid);
|
|
22
|
-
return JSON.parse(text) as T;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** True iff Pinata creds are reachable in env. Cheap to call repeatedly. */
|
|
26
|
-
export function isPinningConfigured(): boolean {
|
|
27
|
-
return Boolean(process.env["PINATA_JWT"] || (process.env["PINATA_API_KEY"] && process.env["PINATA_SECRET"]));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Pin text content to IPFS via Pinata's v2 `pinFileToIPFS` API. Prefers a JWT
|
|
32
|
-
* (PINATA_JWT, scoped for `pinFileToIPFS`, sent as Bearer), and falls back to a
|
|
33
|
-
* key/secret pair (PINATA_API_KEY + PINATA_SECRET). Returns an `ipfs://<cid>` URI.
|
|
34
|
-
*
|
|
35
|
-
* Throws immediately (not deep inside an autonomous loop) if creds are missing.
|
|
36
|
-
*/
|
|
37
|
-
export async function pinText(content: string, filename = "result.md"): Promise<string> {
|
|
38
|
-
const jwt = process.env["PINATA_JWT"];
|
|
39
|
-
const apiKey = process.env["PINATA_API_KEY"];
|
|
40
|
-
const apiSecret = process.env["PINATA_SECRET"];
|
|
41
|
-
|
|
42
|
-
const blob = new Blob([content], { type: "text/plain" });
|
|
43
|
-
|
|
44
|
-
if (jwt) {
|
|
45
|
-
const form = new FormData();
|
|
46
|
-
form.append("file", blob, filename);
|
|
47
|
-
const res = await fetch("https://api.pinata.cloud/pinning/pinFileToIPFS", {
|
|
48
|
-
method: "POST",
|
|
49
|
-
headers: { Authorization: `Bearer ${jwt}` },
|
|
50
|
-
body: form,
|
|
51
|
-
});
|
|
52
|
-
if (!res.ok) {
|
|
53
|
-
const text = await res.text().catch(() => "");
|
|
54
|
-
throw new Error(`Pinata v2 error ${res.status}: ${text}`);
|
|
55
|
-
}
|
|
56
|
-
const data = await res.json() as { IpfsHash: string };
|
|
57
|
-
return `ipfs://${data.IpfsHash}`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (apiKey && apiSecret) {
|
|
61
|
-
const form = new FormData();
|
|
62
|
-
form.append("file", blob, filename);
|
|
63
|
-
const res = await fetch("https://api.pinata.cloud/pinning/pinFileToIPFS", {
|
|
64
|
-
method: "POST",
|
|
65
|
-
headers: {
|
|
66
|
-
pinata_api_key: apiKey,
|
|
67
|
-
pinata_secret_api_key: apiSecret,
|
|
68
|
-
},
|
|
69
|
-
body: form,
|
|
70
|
-
});
|
|
71
|
-
if (!res.ok) {
|
|
72
|
-
const text = await res.text().catch(() => "");
|
|
73
|
-
throw new Error(`Pinata v1 error ${res.status}: ${text}`);
|
|
74
|
-
}
|
|
75
|
-
const data = await res.json() as { IpfsHash: string };
|
|
76
|
-
return `ipfs://${data.IpfsHash}`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
throw new Error("Set PINATA_JWT (preferred) or PINATA_API_KEY + PINATA_SECRET to pin to IPFS");
|
|
80
|
-
}
|
package/src/metadata.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { pinText } from "./ipfs.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ERC-8004 agent metadata (TZ §4.3 + §12.3).
|
|
5
|
-
*
|
|
6
|
-
* IdentityRegistry.register() stores a URI; everyone reading it expects the
|
|
7
|
-
* referenced JSON to follow this shape. Persistence matters — `data:` URIs
|
|
8
|
-
* break the moment a verifier wants to fetch the manifest after registration,
|
|
9
|
-
* so we always pin to IPFS.
|
|
10
|
-
*/
|
|
11
|
-
export type ArcBountySection = {
|
|
12
|
-
/** Min reputation a poster requires before this agent takes their bounty. */
|
|
13
|
-
min_reputation?: number;
|
|
14
|
-
preferred_categories?: ReadonlyArray<"dev" | "design" | "content" | "data" | "other">;
|
|
15
|
-
min_reward_usdc?: number;
|
|
16
|
-
max_reward_usdc?: number;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type AgentMetadata = {
|
|
20
|
-
name: string;
|
|
21
|
-
description: string;
|
|
22
|
-
agent_type?: string;
|
|
23
|
-
capabilities?: readonly string[];
|
|
24
|
-
version?: string;
|
|
25
|
-
contact?: string;
|
|
26
|
-
|
|
27
|
-
// ArcBounty-specific block — required for agents that want to be discoverable
|
|
28
|
-
// by the autonomous selection in subscribeToNewBounties / runOnce.
|
|
29
|
-
arcbounty?: ArcBountySection;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Validate a metadata blob before pinning. Strict by default — we'd rather
|
|
34
|
-
* fail loudly on init than silently push a broken manifest to IPFS.
|
|
35
|
-
*/
|
|
36
|
-
export function validateAgentMetadata(m: unknown): asserts m is AgentMetadata {
|
|
37
|
-
if (typeof m !== "object" || m === null) throw new Error("metadata must be an object");
|
|
38
|
-
const o = m as Record<string, unknown>;
|
|
39
|
-
if (typeof o.name !== "string" || o.name.length === 0)
|
|
40
|
-
throw new Error("metadata.name must be a non-empty string");
|
|
41
|
-
if (typeof o.description !== "string")
|
|
42
|
-
throw new Error("metadata.description must be a string");
|
|
43
|
-
if (o.capabilities !== undefined && !Array.isArray(o.capabilities))
|
|
44
|
-
throw new Error("metadata.capabilities must be an array of strings");
|
|
45
|
-
if (o.arcbounty !== undefined) {
|
|
46
|
-
const a = o.arcbounty as Record<string, unknown>;
|
|
47
|
-
if (a.min_reputation !== undefined && (typeof a.min_reputation !== "number" || a.min_reputation < 0 || a.min_reputation > 100))
|
|
48
|
-
throw new Error("metadata.arcbounty.min_reputation must be a number in [0, 100]");
|
|
49
|
-
if (a.preferred_categories !== undefined) {
|
|
50
|
-
if (!Array.isArray(a.preferred_categories)) throw new Error("preferred_categories must be an array");
|
|
51
|
-
for (const c of a.preferred_categories as unknown[]) {
|
|
52
|
-
if (typeof c !== "string" || !["dev","design","content","data","other"].includes(c))
|
|
53
|
-
throw new Error(`preferred_categories: invalid category ${String(c)}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
for (const k of ["min_reward_usdc","max_reward_usdc"] as const) {
|
|
57
|
-
const v = a[k];
|
|
58
|
-
if (v !== undefined && (typeof v !== "number" || v < 0)) {
|
|
59
|
-
throw new Error(`metadata.arcbounty.${k} must be a non-negative number`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Pin a validated metadata blob to IPFS and return the `ipfs://<cid>` URI. */
|
|
66
|
-
export async function pinAgentMetadata(meta: AgentMetadata): Promise<string> {
|
|
67
|
-
validateAgentMetadata(meta);
|
|
68
|
-
return pinText(JSON.stringify(meta, null, 2), "agent.json");
|
|
69
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import type { Address, Hash } from "viem";
|
|
2
|
-
|
|
3
|
-
// ─── Config ──────────────────────────────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
export type ArcBountyAgentConfig = {
|
|
6
|
-
/** Private key of the agent wallet (0x-prefixed hex) */
|
|
7
|
-
privateKey: Hash;
|
|
8
|
-
/** Arc RPC URL */
|
|
9
|
-
rpcUrl?: string;
|
|
10
|
-
/** IPFS metadata URI for agent registration (ipfs://Qm...) */
|
|
11
|
-
metadataURI?: string;
|
|
12
|
-
/** BountyAdapter contract address (overrides default) */
|
|
13
|
-
bountyAdapterAddress?: Address;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// ─── On-chain structs (mirror BountyAdapter.sol BountyMeta) ──────────────────
|
|
17
|
-
|
|
18
|
-
export type BountyMeta = {
|
|
19
|
-
jobId: bigint;
|
|
20
|
-
poster: Address;
|
|
21
|
-
reward: bigint;
|
|
22
|
-
deadline: bigint;
|
|
23
|
-
ipfsDescHash: string;
|
|
24
|
-
category: string;
|
|
25
|
-
tags: readonly string[];
|
|
26
|
-
agentId: bigint;
|
|
27
|
-
agentOnly: boolean;
|
|
28
|
-
humanOnly: boolean;
|
|
29
|
-
whitelistedProvider: Address;
|
|
30
|
-
assignedProvider: Address;
|
|
31
|
-
submittedResultHash: string;
|
|
32
|
-
submittedAt: bigint;
|
|
33
|
-
isTaken: boolean;
|
|
34
|
-
// Pending-rejection state
|
|
35
|
-
rejectedAt: bigint;
|
|
36
|
-
rejectionReasonHash: string;
|
|
37
|
-
// Dispute state
|
|
38
|
-
inDispute: boolean;
|
|
39
|
-
resolved: boolean;
|
|
40
|
-
disputeInitiator: Address;
|
|
41
|
-
disputeRaisedAt: bigint;
|
|
42
|
-
disputeReasonHash: string;
|
|
43
|
-
disputeResponseHash: string;
|
|
44
|
-
disputeRulingHash: string;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type ReputationScore = {
|
|
48
|
-
averageScore: bigint;
|
|
49
|
-
totalFeedbacks: bigint;
|
|
50
|
-
totalJobs: bigint;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// ─── SDK-level types ──────────────────────────────────────────────────────────
|
|
54
|
-
|
|
55
|
-
export type OpenBountiesFilter = {
|
|
56
|
-
category?: string;
|
|
57
|
-
agentOnly?: boolean;
|
|
58
|
-
humanOnly?: boolean;
|
|
59
|
-
maxReward?: number; // in USDC dollars
|
|
60
|
-
minReward?: number;
|
|
61
|
-
offset?: number;
|
|
62
|
-
limit?: number;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export type CreateBountyOptions = {
|
|
66
|
-
/** Reward in USDC dollars (will be scaled by 1e6) */
|
|
67
|
-
rewardUsdc: number;
|
|
68
|
-
/** Unix seconds OR a Date OR seconds-from-now (if < 1e9 treated as duration) */
|
|
69
|
-
deadline: number | Date;
|
|
70
|
-
/** Pre-pinned IPFS CID for the description (ipfs://... or bafy...) */
|
|
71
|
-
descriptionCid?: string;
|
|
72
|
-
/** Or raw markdown — will be pinned for you */
|
|
73
|
-
descriptionText?: string;
|
|
74
|
-
category: "dev" | "design" | "content" | "data" | "other";
|
|
75
|
-
tags?: string[];
|
|
76
|
-
/** Optional whitelisted provider — only this address may take */
|
|
77
|
-
provider?: Address;
|
|
78
|
-
agentOnly?: boolean;
|
|
79
|
-
humanOnly?: boolean;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type SubmitWorkOptions = {
|
|
83
|
-
/** Raw text/markdown result — will be pinned to IPFS */
|
|
84
|
-
text?: string;
|
|
85
|
-
/** Pre-computed IPFS CID (ipfs://...) — skips pinning */
|
|
86
|
-
cid?: string;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export type DisputeEvidenceOptions = {
|
|
90
|
-
/** Raw evidence text — will be pinned to IPFS */
|
|
91
|
-
text?: string;
|
|
92
|
-
/** Pre-computed IPFS CID — skips pinning */
|
|
93
|
-
cid?: string;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export type AgentInfo = {
|
|
97
|
-
agentId: bigint;
|
|
98
|
-
address: Address;
|
|
99
|
-
metadataURI: string;
|
|
100
|
-
reputation: ReputationScore;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export type TxResult = {
|
|
104
|
-
hash: Hash;
|
|
105
|
-
};
|
package/tsconfig.json
DELETED