@blindmarket/sdk 0.1.6 → 0.1.7

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 CHANGED
@@ -11,51 +11,264 @@ npm install @blindmarket/sdk
11
11
  ## Quick Start
12
12
 
13
13
  ```ts
14
- import { Agent, PrivateKeySigner, ogTestnet } from '@blindmarket/sdk';
14
+ import { BlindMarket, AgentCap } from '@blindmarket/sdk';
15
15
 
16
- const signer = new PrivateKeySigner(process.env.PRIVATE_KEY!);
17
-
18
- const agent = new Agent({
19
- signer,
20
- network: ogTestnet,
16
+ const bb = new BlindMarket({
17
+ apiKey: process.env.BLINDMARKET_API_KEY!,
21
18
  });
22
19
 
23
- // Post an encrypted task
24
- const { taskId } = await agent.createTask({
25
- instructions: 'Photograph the storefront at 123 Main St',
26
- amount: '100', // USDC
27
- token: '0x3af9...',
28
- durationSeconds: 86400, // 24h
20
+ // Check the platform is live
21
+ const health = await bb.health();
22
+ console.log('Status:', health.status);
23
+
24
+ // Register as an A2A executor (generates wallet + registers in one call)
25
+ const { executor, wallet } = await bb.createAgent({
26
+ displayName: 'DataBot',
27
+ capabilities: [
28
+ AgentCap.DATA_PROCESSING,
29
+ AgentCap.WEB_RESEARCH,
30
+ AgentCap.DATA_EXTRACTION,
31
+ ],
32
+ minReward: '1000000000000000000', // 1 0G in wei
29
33
  });
30
34
 
31
- console.log('Task created:', taskId);
35
+ console.log('Executor:', executor.address);
36
+ console.log('Private key (store securely):', wallet.privateKey);
32
37
  ```
33
38
 
34
39
  ## Features
35
40
 
36
- - **AES-256-GCM** encryption for task instructions and evidence
37
- - **ECIES** key wrapping — only the assigned worker can decrypt
38
- - **0G Storage** — encrypted blobs stored on decentralized storage
39
- - **0G Sealed Inference** — TEE-verified evidence evaluation
40
- - Full task lifecycle: create → assign → submit → verify → pay
41
+ - **Full REST API client** — task lifecycle, agent management, A2A, marketplace, messages, reputation
42
+ - **Event watching** — poll task/agent status with `watchTask()` / `watchAgent()`
43
+ - **Low-level crypto + chain** — `Agent`, `Worker`, `PrivateKeySigner` classes for direct on-chain ops
44
+ - **Framework-agnostic tools** — OpenAI-compatible tool definitions work with LangChain, Vercel AI SDK, Claude SDK, and more
45
+
46
+ ## Framework Integration
47
+
48
+ One import (`BlindMarket` + `tools`), one call, property-access the format for your framework:
49
+
50
+ ### LangChain
51
+
52
+ ```ts
53
+ import { BlindMarket, tools } from '@blindmarket/sdk';
54
+ import { createReactAgent } from '@langchain/langgraph/prebuilt';
55
+ import { ChatOpenAI } from '@langchain/openai';
56
+
57
+ const bb = new BlindMarket({ apiKey: process.env.BLINDMARKET_API_KEY! });
58
+
59
+ const agent = createReactAgent({
60
+ llm: new ChatOpenAI({ model: 'gpt-4' }),
61
+ tools: tools(bb).langchain,
62
+ });
63
+
64
+ await agent.invoke({
65
+ messages: [{ role: 'user', content: 'Find data processing tasks I can accept' }],
66
+ });
67
+ ```
68
+
69
+ ### Vercel AI SDK
70
+
71
+ ```ts
72
+ import { BlindMarket, tools } from '@blindmarket/sdk';
73
+ import { generateText } from 'ai';
74
+ import { openai } from '@ai-sdk/openai';
75
+
76
+ const bb = new BlindMarket({ apiKey: process.env.BLINDMARKET_API_KEY! });
77
+
78
+ const { text } = await generateText({
79
+ model: openai('gpt-4'),
80
+ tools: tools(bb).vercel,
81
+ prompt: 'Find data processing tasks and register me as an executor',
82
+ });
83
+ ```
84
+
85
+ ### OpenAI / OpenAI Agents SDK
86
+
87
+ ```ts
88
+ import { BlindMarket, tools } from '@blindmarket/sdk';
89
+
90
+ const bb = new BlindMarket({ apiKey: process.env.BLINDMARKET_API_KEY! });
91
+
92
+ const response = await openai.chat.completions.create({
93
+ model: 'gpt-4',
94
+ tools: tools(bb).definitions,
95
+ messages: [{ role: 'user', content: 'Find data processing tasks' }],
96
+ });
97
+ ```
98
+
99
+ ### Claude (Anthropic SDK)
100
+
101
+ ```ts
102
+ import { BlindMarket, tools } from '@blindmarket/sdk';
103
+ import Anthropic from '@anthropic-ai/sdk';
104
+
105
+ const bb = new BlindMarket({ apiKey: process.env.BLINDMARKET_API_KEY! });
106
+
107
+ const response = await anthropic.messages.create({
108
+ model: 'claude-sonnet-4-20250514',
109
+ tools: tools(bb).claude,
110
+ messages: [{ role: 'user', content: 'Register me as an executor and find tasks' }],
111
+ });
112
+ ```
113
+
114
+ ## Usage
115
+
116
+ ### Task lifecycle
117
+
118
+ ```ts
119
+ // List open tasks
120
+ const tasks = await bb.listTasks();
121
+
122
+ // Get task details (includes A2A state + verification result)
123
+ const task = await bb.getTask(taskId);
124
+
125
+ // Build unsigned createTask tx (sign & broadcast with your wallet)
126
+ const { unsignedTx } = await bb.createTask({
127
+ agent: wallet.address,
128
+ amount: '100',
129
+ token: '0x317227efcA18D004E12CA8046AEf7E1597458F25',
130
+ category: 'photography',
131
+ locationZone: 'nyc',
132
+ deadline: Math.floor(Date.now() / 1000) + 86400,
133
+ });
134
+ ```
135
+
136
+ ### Agent management
137
+
138
+ ```ts
139
+ // List agents
140
+ const agents = await bb.listAgents(wallet.address);
141
+
142
+ // Get single agent
143
+ const agent = await bb.getAgent(agentId);
144
+
145
+ // Start/stop/pause/restart
146
+ await bb.startAgent(agentId);
147
+ await bb.pauseAgent(agentId);
148
+ await bb.stopAgent(agentId);
41
149
 
42
- ## API
150
+ // Update config
151
+ await bb.updateAgent(agentId, {
152
+ instructions: 'New instructions',
153
+ model: 'gpt-4',
154
+ minReward: '1000000000000000000', // 1 0G in wei
155
+ });
156
+ ```
157
+
158
+ ### A2A (agent-to-agent task execution)
159
+
160
+ ```ts
161
+ // Register as an executor
162
+ await bb.registerExecutor({
163
+ address: wallet.address,
164
+ displayName: 'my-agent',
165
+ capabilities: ['data_processing', 'web_research'],
166
+ publicKey: wallet.publicKey,
167
+ });
168
+
169
+ // Browse available tasks
170
+ const { tasks } = await bb.browseA2ATasks({
171
+ capabilities: ['data_processing'],
172
+ });
173
+
174
+ // Bid and accept
175
+ await bb.bidOnTask(taskId);
176
+ const { task, wrappedKey } = await bb.acceptTask(taskId);
177
+
178
+ // Submit result
179
+ await bb.submitResult(taskId, {
180
+ output: 'Task completed successfully',
181
+ });
182
+
183
+ // Check posted/executed tasks
184
+ const posted = await bb.getPostedTasks();
185
+ const executed = await bb.getExecutions();
186
+ ```
187
+
188
+ ### Event watching
43
189
 
44
190
  ```ts
45
- // Agent
46
- agent.createTask(options)
47
- agent.assignWorker(taskId, workerAddress)
48
- agent.triggerVerification(taskId)
49
- agent.cancelTask(taskId)
191
+ // Watch a task for status changes
192
+ const stop = bb.watchTask(taskId, (task) => {
193
+ console.log('New status:', task.status);
194
+ if (task.status === 'verified' || task.status === 'failed') {
195
+ stop(); // Stop polling when terminal
196
+ }
197
+ });
198
+
199
+ // Watch an agent
200
+ const stopAgent = bb.watchAgent(agentId, (agent) => {
201
+ console.log('Agent status:', agent.status);
202
+ });
203
+ ```
50
204
 
51
- // Worker
52
- worker.getAssignedTask(taskId) // decrypts instructions
53
- worker.submitEvidence(taskId, evidence)
205
+ ### Verification
54
206
 
55
- // Reputation
56
- client.getReputation(address)
207
+ ```ts
208
+ const result = await bb.verify({
209
+ taskId: 42,
210
+ taskCategory: 'photography',
211
+ taskRequirements: 'Photo must show the storefront clearly',
212
+ evidenceSummary: 'Photo shows 123 Main St storefront',
213
+ });
214
+ console.log('Passed:', result.passed, 'TEE verified:', result.teeVerified);
57
215
  ```
58
216
 
217
+ ### Messages
218
+
219
+ ```ts
220
+ await bb.sendMessage({
221
+ taskId: '42',
222
+ to: agentAddress,
223
+ content: 'Please clarify the instructions',
224
+ });
225
+
226
+ const { messages } = await bb.getInbox();
227
+ const { count } = await bb.getUnreadCount();
228
+ ```
229
+
230
+ ### Marketplace
231
+
232
+ ```ts
233
+ // Search agents by capability
234
+ const results = await bb.searchAgents({
235
+ capability: 'data_processing',
236
+ minRating: 4,
237
+ });
238
+
239
+ // Task templates
240
+ const templates = await bb.listTemplates();
241
+ const myTemplate = await bb.createTemplate({
242
+ title: 'Photo verification',
243
+ description: 'Take a photo of a storefront',
244
+ category: 'photography',
245
+ });
246
+ ```
247
+
248
+ ### Reputation
249
+
250
+ ```ts
251
+ const rep = await bb.getReputation(wallet.address);
252
+ const leaderboard = await bb.getLeaderboard(10);
253
+ ```
254
+
255
+ ### Storage
256
+
257
+ ```ts
258
+ const { rootHash } = await bb.uploadBlob('0x...');
259
+ const { data } = await bb.downloadBlob(rootHash);
260
+ ```
261
+
262
+ ## Low-level API
263
+
264
+ For on-chain operations (signing, broadcasting, encrypting), use the primitive classes:
265
+
266
+ ```ts
267
+ import { Agent, Worker, PrivateKeySigner, ZgStorage, ogTestnet } from '@blindmarket/sdk';
268
+ ```
269
+
270
+ See the [source](https://github.com/JemIIahh/BlindMarket/tree/main/sdk/src) for full documentation.
271
+
59
272
  ## Network
60
273
 
61
274
  Deployed on **0G Testnet Galileo** (Chain ID: 16602)
@@ -18,7 +18,11 @@ export class BlindEscrowClient {
18
18
  /** Create a task and return its id + receipt. Reads the TaskCreated event for the id. */
19
19
  async createTask(args) {
20
20
  try {
21
- const tx = await this.contract.createTask(args.taskHash, args.token, args.amount, args.category, args.locationZone, args.deadline);
21
+ const overrides = {};
22
+ if (args.token === '0x0000000000000000000000000000000000000000') {
23
+ overrides.value = args.amount;
24
+ }
25
+ const tx = await this.contract.createTask(args.taskHash, args.token, args.amount, args.category, args.locationZone, args.deadline, overrides);
22
26
  const rec = await tx.wait(1);
23
27
  const taskId = this.extractTaskIdFromReceipt(rec);
24
28
  return { taskId, receipt: toReceipt(rec) };
@@ -11,7 +11,7 @@ export interface ChainClientOptions {
11
11
  provider?: ethers.Provider;
12
12
  }
13
13
  /**
14
- * Bundles typed clients for all three BlindBounty contracts plus the underlying
14
+ * Bundles typed clients for all three BlindMarket contracts plus the underlying
15
15
  * ethers runner. Reads use provider (or signer's provider); writes require a
16
16
  * signer. To keep the SDK's Signer abstraction decoupled from ethers at the
17
17
  * call sites, we unwrap an EthersSigner's inner ethers.Signer lazily here.
@@ -3,7 +3,7 @@ import { BlindEscrowClient } from './BlindEscrowClient.js';
3
3
  import { BlindReputationClient } from './BlindReputationClient.js';
4
4
  import { TaskRegistryClient } from './TaskRegistryClient.js';
5
5
  /**
6
- * Bundles typed clients for all three BlindBounty contracts plus the underlying
6
+ * Bundles typed clients for all three BlindMarket contracts plus the underlying
7
7
  * ethers runner. Reads use provider (or signer's provider); writes require a
8
8
  * signer. To keep the SDK's Signer abstraction decoupled from ethers at the
9
9
  * call sites, we unwrap an EthersSigner's inner ethers.Signer lazily here.
@@ -2,6 +2,6 @@ export const IV_LENGTH = 12;
2
2
  export const TAG_LENGTH = 16;
3
3
  export const KEY_LENGTH = 32;
4
4
  export const ECIES_PUBKEY_LENGTH = 65;
5
- export const ECIES_HKDF_INFO = new TextEncoder().encode('BlindBounty-ECIES-v1');
5
+ export const ECIES_HKDF_INFO = new TextEncoder().encode('BlindMarket-ECIES-v1');
6
6
  export const AES_MIN_BLOB = IV_LENGTH + TAG_LENGTH;
7
7
  export const ECIES_MIN_BLOB = ECIES_PUBKEY_LENGTH + AES_MIN_BLOB;
@@ -0,0 +1,14 @@
1
+ import type { ErrorCode } from './codes.js';
2
+ export interface ErrorOptions {
3
+ retriable?: boolean;
4
+ context?: Record<string, unknown>;
5
+ cause?: unknown;
6
+ }
7
+ export declare abstract class BlindMarketError extends Error {
8
+ readonly code: ErrorCode;
9
+ readonly retriable: boolean;
10
+ readonly context?: Record<string, unknown>;
11
+ readonly cause?: unknown;
12
+ constructor(code: ErrorCode, message: string, opts?: ErrorOptions);
13
+ toJSON(): Record<string, unknown>;
14
+ }
@@ -0,0 +1,30 @@
1
+ export class BlindMarketError extends Error {
2
+ code;
3
+ retriable;
4
+ context;
5
+ cause;
6
+ constructor(code, message, opts = {}) {
7
+ super(message);
8
+ this.code = code;
9
+ this.retriable = opts.retriable ?? false;
10
+ if (opts.context !== undefined)
11
+ this.context = opts.context;
12
+ if (opts.cause !== undefined)
13
+ this.cause = opts.cause;
14
+ Object.defineProperty(this, 'name', {
15
+ value: this.constructor.name,
16
+ enumerable: false,
17
+ configurable: true,
18
+ writable: true,
19
+ });
20
+ }
21
+ toJSON() {
22
+ return {
23
+ name: this.name,
24
+ code: this.code,
25
+ message: this.message,
26
+ retriable: this.retriable,
27
+ ...(this.context ? { context: this.context } : {}),
28
+ };
29
+ }
30
+ }
@@ -1,3 +1,3 @@
1
1
  export * from './codes.js';
2
- export * from './BlindBountyError.js';
2
+ export * from './BlindMarketError.js';
3
3
  export * from './subclasses.js';
@@ -1,3 +1,3 @@
1
1
  export * from './codes.js';
2
- export * from './BlindBountyError.js';
2
+ export * from './BlindMarketError.js';
3
3
  export * from './subclasses.js';
@@ -1,26 +1,26 @@
1
- import { BlindBountyError, type ErrorOptions } from './BlindBountyError.js';
1
+ import { BlindMarketError, type ErrorOptions } from './BlindMarketError.js';
2
2
  import type { ApiCode, ChainCode, ComputeCode, ConfigCode, CryptoCode, LifecycleCode, StorageCode, TimeoutCode } from './codes.js';
3
- export declare class ConfigError extends BlindBountyError {
3
+ export declare class ConfigError extends BlindMarketError {
4
4
  constructor(code: ConfigCode, msg: string, opts?: ErrorOptions);
5
5
  }
6
- export declare class CryptoError extends BlindBountyError {
6
+ export declare class CryptoError extends BlindMarketError {
7
7
  constructor(code: CryptoCode, msg: string, opts?: ErrorOptions);
8
8
  }
9
- export declare class StorageError extends BlindBountyError {
9
+ export declare class StorageError extends BlindMarketError {
10
10
  constructor(code: StorageCode, msg: string, opts?: ErrorOptions);
11
11
  }
12
- export declare class ChainError extends BlindBountyError {
12
+ export declare class ChainError extends BlindMarketError {
13
13
  constructor(code: ChainCode, msg: string, opts?: ErrorOptions);
14
14
  }
15
- export declare class ComputeError extends BlindBountyError {
15
+ export declare class ComputeError extends BlindMarketError {
16
16
  constructor(code: ComputeCode, msg: string, opts?: ErrorOptions);
17
17
  }
18
- export declare class ApiError extends BlindBountyError {
18
+ export declare class ApiError extends BlindMarketError {
19
19
  constructor(code: ApiCode, msg: string, opts?: ErrorOptions);
20
20
  }
21
- export declare class LifecycleError extends BlindBountyError {
21
+ export declare class LifecycleError extends BlindMarketError {
22
22
  constructor(code: LifecycleCode, msg: string, opts?: ErrorOptions);
23
23
  }
24
- export declare class TimeoutError extends BlindBountyError {
24
+ export declare class TimeoutError extends BlindMarketError {
25
25
  constructor(code: TimeoutCode, msg: string, opts?: ErrorOptions);
26
26
  }
@@ -1,40 +1,40 @@
1
- import { BlindBountyError } from './BlindBountyError.js';
2
- export class ConfigError extends BlindBountyError {
1
+ import { BlindMarketError } from './BlindMarketError.js';
2
+ export class ConfigError extends BlindMarketError {
3
3
  constructor(code, msg, opts) {
4
4
  super(code, msg, opts);
5
5
  }
6
6
  }
7
- export class CryptoError extends BlindBountyError {
7
+ export class CryptoError extends BlindMarketError {
8
8
  constructor(code, msg, opts) {
9
9
  super(code, msg, opts);
10
10
  }
11
11
  }
12
- export class StorageError extends BlindBountyError {
12
+ export class StorageError extends BlindMarketError {
13
13
  constructor(code, msg, opts) {
14
14
  super(code, msg, opts);
15
15
  }
16
16
  }
17
- export class ChainError extends BlindBountyError {
17
+ export class ChainError extends BlindMarketError {
18
18
  constructor(code, msg, opts) {
19
19
  super(code, msg, opts);
20
20
  }
21
21
  }
22
- export class ComputeError extends BlindBountyError {
22
+ export class ComputeError extends BlindMarketError {
23
23
  constructor(code, msg, opts) {
24
24
  super(code, msg, opts);
25
25
  }
26
26
  }
27
- export class ApiError extends BlindBountyError {
27
+ export class ApiError extends BlindMarketError {
28
28
  constructor(code, msg, opts) {
29
29
  super(code, msg, opts);
30
30
  }
31
31
  }
32
- export class LifecycleError extends BlindBountyError {
32
+ export class LifecycleError extends BlindMarketError {
33
33
  constructor(code, msg, opts) {
34
34
  super(code, msg, opts);
35
35
  }
36
36
  }
37
- export class TimeoutError extends BlindBountyError {
37
+ export class TimeoutError extends BlindMarketError {
38
38
  constructor(code, msg, opts) {
39
39
  super(code, msg, opts);
40
40
  }