@blindmarket/sdk 0.1.7 → 0.1.8

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.
Files changed (133) hide show
  1. package/dist/chain/BlindEscrowClient.d.ts +2 -0
  2. package/dist/chain/BlindEscrowClient.js +14 -6
  3. package/dist/chain/BlindReputationClient.d.ts +3 -0
  4. package/dist/chain/BlindReputationClient.js +3 -1
  5. package/dist/chain/ChainClient.d.ts +5 -2
  6. package/dist/chain/ChainClient.js +5 -0
  7. package/dist/chain/IBlindMarketChain.d.ts +74 -0
  8. package/dist/chain/IBlindMarketChain.js +1 -0
  9. package/dist/chain/TaskRegistryClient.d.ts +2 -1
  10. package/dist/chain/TaskRegistryClient.js +15 -7
  11. package/dist/chain/createChainAdapter.d.ts +25 -0
  12. package/dist/chain/createChainAdapter.js +24 -0
  13. package/dist/chain/domain-types.d.ts +77 -0
  14. package/dist/chain/domain-types.js +1 -0
  15. package/dist/chain/evm/EVMChainAdapter.d.ts +56 -0
  16. package/dist/chain/evm/EVMChainAdapter.js +161 -0
  17. package/dist/chain/evm/index.d.ts +1 -0
  18. package/dist/chain/evm/index.js +1 -0
  19. package/dist/chain/index.d.ts +4 -0
  20. package/dist/chain/index.js +5 -0
  21. package/dist/executor/WorkerRuntime.d.ts +113 -0
  22. package/dist/executor/WorkerRuntime.js +248 -0
  23. package/dist/executor/index.d.ts +1 -0
  24. package/dist/executor/index.js +1 -0
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.js +8 -3
  27. package/dist/network/presets.d.ts +33 -5
  28. package/dist/network/presets.js +35 -8
  29. package/dist/network/resolve.d.ts +12 -3
  30. package/dist/network/resolve.js +15 -7
  31. package/dist/network/types.d.ts +3 -16
  32. package/dist/types.d.ts +1 -1
  33. package/package.json +1 -1
  34. package/src/chain/BlindEscrowClient.ts +15 -6
  35. package/src/chain/BlindReputationClient.ts +6 -1
  36. package/src/chain/ChainClient.ts +9 -3
  37. package/src/chain/IBlindMarketChain.ts +109 -0
  38. package/src/chain/TaskRegistryClient.ts +17 -8
  39. package/src/chain/createChainAdapter.ts +40 -0
  40. package/src/chain/domain-types.ts +92 -0
  41. package/src/chain/evm/EVMChainAdapter.ts +212 -0
  42. package/src/chain/evm/index.ts +1 -0
  43. package/src/chain/index.ts +6 -0
  44. package/src/executor/WorkerRuntime.ts +338 -0
  45. package/src/executor/index.ts +8 -0
  46. package/src/index.ts +23 -4
  47. package/src/network/presets.ts +47 -8
  48. package/src/network/resolve.ts +20 -8
  49. package/src/network/types.ts +18 -16
  50. package/src/signer/index.ts +1 -1
  51. package/src/types.ts +2 -1
  52. package/dist/BlindEscrowClient-CyPuKMge.d.cts +0 -54
  53. package/dist/BlindEscrowClient-R7iGpE-n.d.ts +0 -54
  54. package/dist/KeyStore-Be_SSpCt.d.cts +0 -21
  55. package/dist/KeyStore-k1JgYPJY.d.ts +0 -21
  56. package/dist/Signer-BnqH_qew.d.cts +0 -38
  57. package/dist/Signer-LColE0Uo.d.ts +0 -38
  58. package/dist/Storage-4QOrh7rm.d.ts +0 -17
  59. package/dist/Storage-Cf4IJRMk.d.cts +0 -17
  60. package/dist/TaskRegistryClient-Ch6lYqM_.d.ts +0 -24
  61. package/dist/TaskRegistryClient-CrQjddDc.d.cts +0 -24
  62. package/dist/aes-J-7HrHze.d.cts +0 -17
  63. package/dist/aes-J-7HrHze.d.ts +0 -17
  64. package/dist/agent/index.cjs +0 -425
  65. package/dist/agent/index.cjs.map +0 -1
  66. package/dist/agent/index.d.cts +0 -63
  67. package/dist/agent/index.js.map +0 -1
  68. package/dist/api/index.cjs +0 -4
  69. package/dist/api/index.cjs.map +0 -1
  70. package/dist/api/index.d.cts +0 -2
  71. package/dist/api/index.js.map +0 -1
  72. package/dist/chain/index.cjs +0 -2484
  73. package/dist/chain/index.cjs.map +0 -1
  74. package/dist/chain/index.d.cts +0 -2305
  75. package/dist/chain/index.js.map +0 -1
  76. package/dist/compute/index.cjs +0 -4
  77. package/dist/compute/index.cjs.map +0 -1
  78. package/dist/compute/index.d.cts +0 -2
  79. package/dist/compute/index.js.map +0 -1
  80. package/dist/crypto/index.cjs +0 -424
  81. package/dist/crypto/index.cjs.map +0 -1
  82. package/dist/crypto/index.d.cts +0 -74
  83. package/dist/crypto/index.js.map +0 -1
  84. package/dist/errors/BlindBountyError.d.ts +0 -14
  85. package/dist/errors/BlindBountyError.js +0 -30
  86. package/dist/errors/index.cjs +0 -136
  87. package/dist/errors/index.cjs.map +0 -1
  88. package/dist/errors/index.d.cts +0 -60
  89. package/dist/errors/index.js.map +0 -1
  90. package/dist/events/index.cjs +0 -41
  91. package/dist/events/index.cjs.map +0 -1
  92. package/dist/events/index.d.cts +0 -61
  93. package/dist/events/index.js.map +0 -1
  94. package/dist/index.cjs +0 -4
  95. package/dist/index.cjs.map +0 -1
  96. package/dist/index.d.cts +0 -2
  97. package/dist/index.js.map +0 -1
  98. package/dist/keystore/index.cjs +0 -335
  99. package/dist/keystore/index.cjs.map +0 -1
  100. package/dist/keystore/index.d.cts +0 -23
  101. package/dist/keystore/index.js.map +0 -1
  102. package/dist/mcp.d.ts +0 -23
  103. package/dist/mcp.js +0 -101
  104. package/dist/network/index.cjs +0 -74
  105. package/dist/network/index.cjs.map +0 -1
  106. package/dist/network/index.d.cts +0 -36
  107. package/dist/network/index.js.map +0 -1
  108. package/dist/signer/index.cjs +0 -121
  109. package/dist/signer/index.cjs.map +0 -1
  110. package/dist/signer/index.d.cts +0 -40
  111. package/dist/signer/index.js.map +0 -1
  112. package/dist/storage/ZgStorage.d.ts +0 -24
  113. package/dist/storage/ZgStorage.js +0 -102
  114. package/dist/storage/index.cjs +0 -221
  115. package/dist/storage/index.cjs.map +0 -1
  116. package/dist/storage/index.d.cts +0 -44
  117. package/dist/storage/index.js.map +0 -1
  118. package/dist/testing/index.cjs +0 -4
  119. package/dist/testing/index.cjs.map +0 -1
  120. package/dist/testing/index.d.cts +0 -2
  121. package/dist/testing/index.js.map +0 -1
  122. package/dist/types-BOG5Ub1z.d.cts +0 -31
  123. package/dist/types-BOG5Ub1z.d.ts +0 -31
  124. package/dist/types-V7_ZmUb-.d.cts +0 -19
  125. package/dist/types-hAsITUQ7.d.ts +0 -19
  126. package/dist/verifier/index.cjs +0 -4
  127. package/dist/verifier/index.cjs.map +0 -1
  128. package/dist/verifier/index.d.cts +0 -2
  129. package/dist/verifier/index.js.map +0 -1
  130. package/dist/worker/index.cjs +0 -382
  131. package/dist/worker/index.cjs.map +0 -1
  132. package/dist/worker/index.d.cts +0 -58
  133. package/dist/worker/index.js.map +0 -1
@@ -0,0 +1,338 @@
1
+ import { BlindMarket } from '../index.js';
2
+ import { eciesDecrypt, aesDecrypt } from '../crypto/index.js';
3
+ import type {
4
+ A2ATaskState, AgentCapability, ExecutorProfile, Message,
5
+ } from '../types.js';
6
+
7
+ // ── Config ──────────────────────────────────────────────────────────────────
8
+
9
+ export interface WorkerRuntimeConfig {
10
+ apiKey: string;
11
+ apiBase?: string;
12
+ displayName: string;
13
+ capabilities: AgentCapability[];
14
+ executeTask: ExecuteTaskHandler;
15
+ existingPrivateKey?: string;
16
+ existingAddress?: string;
17
+ existingPublicKey?: string;
18
+ minReward?: string;
19
+ preferredCapabilities?: AgentCapability[];
20
+ browseIntervalMs?: number;
21
+ watchIntervalMs?: number;
22
+ maxConcurrentTasks?: number;
23
+ }
24
+
25
+ // ── Types ───────────────────────────────────────────────────────────────────
26
+
27
+ export type ExecuteTaskHandler = (ctx: TaskContext) => Promise<Record<string, unknown>>;
28
+
29
+ export interface TaskContext {
30
+ taskId: string;
31
+ task: A2ATaskState;
32
+ instructions: string;
33
+ }
34
+
35
+ export interface TaskExecutionInfo {
36
+ taskId: string;
37
+ status: 'bidding' | 'assigned' | 'working' | 'submitted' | 'completed' | 'failed';
38
+ task?: A2ATaskState;
39
+ error?: string;
40
+ startedAt: number;
41
+ }
42
+
43
+ export type WorkerRuntimeEvent =
44
+ | { type: 'started' }
45
+ | { type: 'stopped' }
46
+ | { type: 'paused' }
47
+ | { type: 'resumed' }
48
+ | { type: 'registered'; profile: ExecutorProfile }
49
+ | { type: 'task_found'; taskId: string; task: A2ATaskState }
50
+ | { type: 'task_bidded'; taskId: string }
51
+ | { type: 'task_assigned'; taskId: string }
52
+ | { type: 'task_accepted'; taskId: string }
53
+ | { type: 'task_working'; taskId: string }
54
+ | { type: 'task_executed'; taskId: string }
55
+ | { type: 'task_submitted'; taskId: string; result: Record<string, unknown> }
56
+ | { type: 'task_failed'; taskId: string; error: string }
57
+ | { type: 'message_received'; message: Message; count: number }
58
+ | { type: 'browse_done'; found: number }
59
+ | { type: 'error'; error: string };
60
+
61
+ // ── Defaults ────────────────────────────────────────────────────────────────
62
+
63
+ const DEFAULTS = {
64
+ browseIntervalMs: 15_000,
65
+ watchIntervalMs: 5_000,
66
+ maxConcurrentTasks: 3,
67
+ };
68
+
69
+ // ── WorkerRuntime ───────────────────────────────────────────────────────────
70
+
71
+ export class WorkerRuntime {
72
+ private bb: BlindMarket;
73
+ private config: WorkerRuntimeConfig & typeof DEFAULTS;
74
+ private wallet?: { address: string; privateKey: string; publicKey: string };
75
+ private profile?: ExecutorProfile;
76
+ private running = false;
77
+ private paused = false;
78
+ private browseTimer?: ReturnType<typeof setInterval>;
79
+ private watchTimers = new Map<string, ReturnType<typeof setInterval>>();
80
+ private executions = new Map<string, TaskExecutionInfo>();
81
+ private listeners = new Set<(event: WorkerRuntimeEvent) => void>();
82
+
83
+ constructor(config: WorkerRuntimeConfig) {
84
+ this.config = { ...DEFAULTS, ...config };
85
+ this.bb = new BlindMarket({ apiKey: config.apiKey, apiBase: config.apiBase });
86
+ }
87
+
88
+ // ── Status ──────────────────────────────────────────────────────────────
89
+
90
+ get isRunning(): boolean {
91
+ return this.running;
92
+ }
93
+
94
+ get isPaused(): boolean {
95
+ return this.paused;
96
+ }
97
+
98
+ get activeExecutions(): TaskExecutionInfo[] {
99
+ return [...this.executions.values()];
100
+ }
101
+
102
+ /** Get own executor profile (available after start). */
103
+ get executorProfile(): ExecutorProfile | undefined {
104
+ return this.profile;
105
+ }
106
+
107
+ /** Get own wallet info (available after start). */
108
+ get executorWallet(): { address: string; publicKey: string } | undefined {
109
+ return this.wallet;
110
+ }
111
+
112
+ // ── Events ──────────────────────────────────────────────────────────────
113
+
114
+ on(listener: (event: WorkerRuntimeEvent) => void): () => void {
115
+ this.listeners.add(listener);
116
+ return () => this.listeners.delete(listener);
117
+ }
118
+
119
+ private emit(event: WorkerRuntimeEvent): void {
120
+ for (const l of this.listeners) l(event);
121
+ }
122
+
123
+ // ── Lifecycle ───────────────────────────────────────────────────────────
124
+
125
+ async start(): Promise<ExecutorProfile> {
126
+ if (this.running) return this.profile!;
127
+
128
+ // 1. Register or restore executor
129
+ if (this.config.existingPrivateKey && this.config.existingAddress && this.config.existingPublicKey) {
130
+ this.wallet = {
131
+ address: this.config.existingAddress,
132
+ privateKey: this.config.existingPrivateKey,
133
+ publicKey: this.config.existingPublicKey,
134
+ };
135
+ // Fetch existing profile — backend identifies by API key
136
+ const result = await this.bb.getExecutorProfile();
137
+ this.profile = result.agent;
138
+ } else {
139
+ const result = await this.bb.createAgent({
140
+ displayName: this.config.displayName,
141
+ capabilities: this.config.capabilities,
142
+ minReward: this.config.minReward,
143
+ preferredCapabilities: this.config.preferredCapabilities,
144
+ });
145
+ this.wallet = {
146
+ address: result.wallet.address,
147
+ privateKey: result.wallet.privateKey,
148
+ publicKey: result.wallet.publicKey,
149
+ };
150
+ this.profile = result.executor;
151
+ }
152
+
153
+ this.emit({ type: 'registered', profile: this.profile });
154
+
155
+ // 2. Start the browse loop
156
+ this.running = true;
157
+ this.startBrowseLoop();
158
+ this.emit({ type: 'started' });
159
+
160
+ return this.profile;
161
+ }
162
+
163
+ stop(): void {
164
+ this.running = false;
165
+ if (this.browseTimer) {
166
+ clearInterval(this.browseTimer);
167
+ this.browseTimer = undefined;
168
+ }
169
+ for (const t of this.watchTimers.values()) clearInterval(t);
170
+ this.watchTimers.clear();
171
+ this.emit({ type: 'stopped' });
172
+ }
173
+
174
+ pause(): void {
175
+ if (!this.running || this.paused) return;
176
+ this.paused = true;
177
+ this.emit({ type: 'paused' });
178
+ }
179
+
180
+ resume(): void {
181
+ if (!this.running || !this.paused) return;
182
+ this.paused = false;
183
+ this.emit({ type: 'resumed' });
184
+ // Immediately browse instead of waiting for next interval
185
+ this.browse();
186
+ }
187
+
188
+ // ── Browse loop ─────────────────────────────────────────────────────────
189
+
190
+ private startBrowseLoop(): void {
191
+ const ms = this.config.browseIntervalMs;
192
+ this.browseTimer = setInterval(() => this.browse(), ms);
193
+ this.browse();
194
+ }
195
+
196
+ private async browse(): Promise<void> {
197
+ if (this.paused) return;
198
+ try {
199
+ const active = this.activeExecutions;
200
+ const inFlight = active.filter(e => e.status === 'bidding' || e.status === 'working').length;
201
+ if (inFlight >= this.config.maxConcurrentTasks) return;
202
+
203
+ const result = await this.bb.browseA2ATasks({
204
+ capabilities: this.config.capabilities,
205
+ });
206
+
207
+ this.emit({ type: 'browse_done', found: result.tasks.length });
208
+
209
+ for (const task of result.tasks) {
210
+ if (this.executions.has(task.taskId)) continue;
211
+ if (task.status !== 'open' && task.status !== 'bidding') continue;
212
+ if (task.executorAddress && task.executorAddress !== this.wallet?.address) continue;
213
+
214
+ this.executions.set(task.taskId, {
215
+ taskId: task.taskId,
216
+ status: 'bidding',
217
+ task,
218
+ startedAt: Date.now(),
219
+ });
220
+
221
+ this.emit({ type: 'task_found', taskId: task.taskId, task });
222
+
223
+ await this.bb.bidOnTask(task.taskId);
224
+ this.emit({ type: 'task_bidded', taskId: task.taskId });
225
+
226
+ this.watchForAssignment(task.taskId);
227
+ }
228
+ } catch (err) {
229
+ this.emit({ type: 'error', error: `Browse failed: ${err}` });
230
+ }
231
+ }
232
+
233
+ // ── Assignment watching ─────────────────────────────────────────────────
234
+
235
+ private watchForAssignment(taskId: string): void {
236
+ if (!this.running) return;
237
+ const ms = this.config.watchIntervalMs;
238
+ const timer = setInterval(async () => {
239
+ if (!this.running || this.paused) return;
240
+ try {
241
+ const detail = await this.bb.getTask(taskId);
242
+ const a2a = detail.a2aState;
243
+ if (!a2a) return;
244
+
245
+ if (a2a.status === 'assigned') {
246
+ clearInterval(timer);
247
+ this.watchTimers.delete(taskId);
248
+ this.emit({ type: 'task_assigned', taskId });
249
+ await this.executeTask(taskId, a2a);
250
+ }
251
+ } catch {
252
+ // Retry next tick
253
+ }
254
+ }, ms);
255
+ this.watchTimers.set(taskId, timer);
256
+ }
257
+
258
+ // ── Task execution ──────────────────────────────────────────────────────
259
+
260
+ private async executeTask(taskId: string, a2a: A2ATaskState): Promise<void> {
261
+ const exec = this.executions.get(taskId);
262
+ if (!exec) return;
263
+
264
+ try {
265
+ exec.status = 'assigned';
266
+
267
+ // Accept task — get the ECIES-wrapped AES key
268
+ const acceptResult = await this.bb.acceptTask(taskId);
269
+ exec.task = acceptResult.task;
270
+ this.emit({ type: 'task_accepted', taskId });
271
+
272
+ // Get full task detail for the storage root hash
273
+ const detail = await this.bb.getTask(taskId);
274
+ const taskHash = detail.taskHash;
275
+
276
+ // Decrypt the wrapped key with the worker's private key
277
+ let instructions = '';
278
+ if (acceptResult.wrappedKey && taskHash) {
279
+ const wrappedBytes = this.decodeWrappedKey(acceptResult.wrappedKey);
280
+ const aesKey = await eciesDecrypt(wrappedBytes, this.wallet!.privateKey);
281
+
282
+ // Download ciphertext from storage via REST API
283
+ const storageResult = await this.bb.downloadBlob(taskHash);
284
+ const ciphertext = this.hexToBytes(storageResult.data);
285
+
286
+ // AES decrypt to get plaintext instructions
287
+ const plaintext = await aesDecrypt(ciphertext, aesKey);
288
+ instructions = new TextDecoder().decode(plaintext);
289
+ }
290
+
291
+ exec.status = 'working';
292
+ this.emit({ type: 'task_working', taskId });
293
+
294
+ // Call the user-provided execution handler with decrypted instructions
295
+ const result = await this.config.executeTask({
296
+ taskId,
297
+ task: acceptResult.task,
298
+ instructions,
299
+ });
300
+
301
+ exec.status = 'submitted';
302
+ this.emit({ type: 'task_executed', taskId });
303
+
304
+ // Submit result
305
+ const submitResult = await this.bb.submitResult(taskId, result);
306
+
307
+ exec.status = 'completed';
308
+ this.emit({ type: 'task_submitted', taskId, result: submitResult });
309
+ } catch (err) {
310
+ exec.status = 'failed';
311
+ exec.error = String(err);
312
+ this.emit({ type: 'task_failed', taskId, error: String(err) });
313
+ }
314
+ }
315
+
316
+ // ── Helpers ─────────────────────────────────────────────────────────────
317
+
318
+ private decodeWrappedKey(wrappedKey: Record<string, string>): Uint8Array {
319
+ // Backend returns wrapped key as hex or base64 in a record
320
+ const hex = Object.values(wrappedKey)[0];
321
+ if (!hex) throw new Error('Empty wrapped key');
322
+ const clean = hex.startsWith('0x') ? hex.slice(2) : hex;
323
+ const bytes = new Uint8Array(clean.length / 2);
324
+ for (let i = 0; i < bytes.length; i++) {
325
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
326
+ }
327
+ return bytes;
328
+ }
329
+
330
+ private hexToBytes(hex: string): Uint8Array {
331
+ const clean = hex.startsWith('0x') ? hex.slice(2) : hex;
332
+ const bytes = new Uint8Array(clean.length / 2);
333
+ for (let i = 0; i < bytes.length; i++) {
334
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
335
+ }
336
+ return bytes;
337
+ }
338
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ WorkerRuntime,
3
+ type WorkerRuntimeConfig,
4
+ type ExecuteTaskHandler,
5
+ type TaskContext,
6
+ type TaskExecutionInfo,
7
+ type WorkerRuntimeEvent,
8
+ } from './WorkerRuntime.js';
package/src/index.ts CHANGED
@@ -200,7 +200,7 @@ export class BlindMarket {
200
200
  return this.req('POST', '/api/v1/submissions/submit', params);
201
201
  }
202
202
 
203
- // ── Agent deployment & management ────────────────────────────────────────
203
+ // ── Agent deployment & management ─────────────────────────────────────────
204
204
 
205
205
  /**
206
206
  * Deploy a new agent. The backend generates a wallet, mints an INFT,
@@ -382,7 +382,7 @@ export class BlindMarket {
382
382
  reasoning: string;
383
383
  teeVerified?: boolean;
384
384
  }> {
385
- return this.req('POST', '/api/v1/verification/trigger', {
385
+ return this.req('POST', '/api/v1/verification/verify', {
386
386
  taskId: params.taskId,
387
387
  taskCategory: params.taskCategory,
388
388
  taskRequirements: params.taskRequirements,
@@ -424,7 +424,7 @@ export class BlindMarket {
424
424
  return this.req<{ data: Hex }>('GET', `/api/v1/storage/${rootHash}`);
425
425
  }
426
426
 
427
- // ── Messages ────────────────────────────────────────────────────────────
427
+ // ── Messages ─────────────────────────────────────────────────────────────
428
428
 
429
429
  /** Send a message to another user or agent. */
430
430
  async sendMessage(params: {
@@ -614,4 +614,23 @@ export {
614
614
  } from './tools/index.js';
615
615
  export type { Tool, ToolKit, ToolDefinition } from './tools/types.js';
616
616
  export type { BlindMarketTools } from './tools/index.js';
617
- export * from './types.js';
617
+ export * from './executor/index.js';
618
+ export * from './types.js';
619
+
620
+ // Chain abstraction layer
621
+ export { EVMChainAdapter } from './chain/evm/index.js';
622
+ export { createChainAdapter } from './chain/createChainAdapter.js';
623
+ export type { CreateChainAdapterOptions } from './chain/createChainAdapter.js';
624
+ export type { IBlindMarketChain } from './chain/IBlindMarketChain.js';
625
+ export type {
626
+ Network,
627
+ EVMNetwork,
628
+ BlockchainType,
629
+ CreateTaskParams,
630
+ DomainTask,
631
+ DomainTaskMeta,
632
+ DomainReputation,
633
+ DomainTxReceipt,
634
+ ChainSigner,
635
+ } from './chain/domain-types.js';
636
+ export { isEVMNetwork } from './network/resolve.js';
@@ -1,16 +1,22 @@
1
- import type { Network } from './types.js';
1
+ import type { Network } from '../chain/domain-types.js';
2
2
 
3
3
  /**
4
4
  * Known-good network presets. Addresses pinned per SDK version so upgrading
5
5
  * the SDK cannot silently move contracts under a consumer.
6
- *
7
- * testnet = 0G Galileo (chainId 16602) — addresses from
8
- * contracts/deployments/0g-testnet.json (deployed 2026-04-15).
9
6
  */
7
+
8
+ export type NetworkName =
9
+ | 'testnet' // deprecated alias → og-testnet
10
+ | 'og-testnet'
11
+ | 'og-mainnet';
12
+
10
13
  export const networks = {
11
- testnet: {
14
+ // ── 0G EVM chains ─────────────────────────────────────────────────────
15
+
16
+ 'og-testnet': {
12
17
  name: '0g-galileo-testnet',
13
- chainId: 16602n,
18
+ chainType: 'evm' as const,
19
+ chainId: 16602,
14
20
  rpc: ['https://evmrpc-testnet.0g.ai'],
15
21
  contracts: {
16
22
  escrow: '0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681',
@@ -22,6 +28,39 @@ export const networks = {
22
28
  broker: 'https://broker.testnet.0g.ai',
23
29
  explorer: 'https://chainscan-galileo.0g.ai',
24
30
  },
25
- } as const satisfies Record<string, Network>;
26
31
 
27
- export type NetworkName = keyof typeof networks;
32
+ 'og-mainnet': {
33
+ name: '0g-mainnet',
34
+ chainType: 'evm' as const,
35
+ chainId: 16661,
36
+ rpc: ['https://evmrpc.0g.ai'],
37
+ contracts: {
38
+ escrow: '0x3d0374963DaaD43e31d42373eb11156A8e8ce2Ff',
39
+ registry: '0x9CCF9c196006B573FaA9C9c9CebDd1296dbd5cE0',
40
+ reputation: '0x3af9232009C5da30AdA366B6E09849A040162A1a',
41
+ usdc: '0x0000000000000000000000000000000000000000',
42
+ },
43
+ indexer: 'https://indexer-storage-turbo.0g.ai',
44
+ broker: 'https://broker.0g.ai',
45
+ explorer: 'https://chainscan.0g.ai',
46
+ },
47
+
48
+ // ── Backward-compat alias ──────────────────────────────────────────────
49
+ // Kept so existing code referencing 'testnet' doesn't break.
50
+
51
+ testnet: {
52
+ name: '0g-galileo-testnet',
53
+ chainType: 'evm' as const,
54
+ chainId: 16602,
55
+ rpc: ['https://evmrpc-testnet.0g.ai'],
56
+ contracts: {
57
+ escrow: '0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681',
58
+ registry: '0xeE52d780A47F77E8a4a1cEb236e3C65A48FbD828',
59
+ reputation: '0x4A6374Fae37E19E69ba43E7cf6994AC15F63256e',
60
+ usdc: '0x317227efcA18D004E12CA8046AEf7E1597458F25',
61
+ },
62
+ indexer: 'https://indexer-storage-testnet-turbo.0g.ai',
63
+ broker: 'https://broker.testnet.0g.ai',
64
+ explorer: 'https://chainscan-galileo.0g.ai',
65
+ },
66
+ } as const satisfies Record<NetworkName, Network>;
@@ -1,19 +1,31 @@
1
1
  import { ConfigError } from '../errors/index.js';
2
2
  import { networks, type NetworkName } from './presets.js';
3
- import type { Network } from './types.js';
3
+ import type { Network } from '../chain/domain-types.js';
4
4
 
5
5
  /**
6
- * Resolve a preset name or a literal Network object into the canonical
7
- * Network used throughout the SDK. Throws ConfigError for unknown names.
6
+ * Resolve a network preset name or a Network object to a canonical Network.
7
+ *
8
+ * When given a string, looks up the preset. When given a Network object,
9
+ * returns it as-is (pass-through for callers that already have a resolved
10
+ * network config).
8
11
  */
9
12
  export function resolveNetwork(arg: NetworkName | Network): Network {
10
13
  if (typeof arg === 'string') {
11
- const preset = (networks as Record<string, Network | undefined>)[arg];
12
- if (!preset) {
13
- const known = Object.keys(networks).join(', ');
14
- throw new ConfigError('CONFIG/INVALID_NETWORK', `unknown network '${arg}' (known: ${known})`);
14
+ const net = networks[arg];
15
+ if (!net) {
16
+ throw new ConfigError(
17
+ 'CONFIG/INVALID_NETWORK',
18
+ `Unknown network: "${arg}". Known presets: ${Object.keys(networks).join(', ')}`,
19
+ );
15
20
  }
16
- return preset;
21
+ return net as unknown as Network;
17
22
  }
18
23
  return arg;
19
24
  }
25
+
26
+ /**
27
+ * Type guard: check if a Network is an EVM network.
28
+ */
29
+ export function isEVMNetwork(network: Network): network is Network & { chainType: 'evm' } {
30
+ return network.chainType === 'evm';
31
+ }
@@ -1,18 +1,20 @@
1
- import type { Address } from '../types.js';
1
+ import type {
2
+ Network,
3
+ EVMNetwork,
4
+ } from '../chain/domain-types.js';
5
+ import type { NetworkName } from './presets.js';
2
6
 
3
- export interface NetworkContracts {
4
- escrow: Address;
5
- registry: Address;
6
- reputation: Address;
7
- usdc: Address;
8
- }
7
+ export type {
8
+ Network,
9
+ EVMNetwork,
10
+ NetworkBase,
11
+ BlockchainType,
12
+ CreateTaskParams,
13
+ DomainTask,
14
+ DomainTaskMeta,
15
+ DomainReputation,
16
+ DomainTxReceipt,
17
+ ChainSigner,
18
+ } from '../chain/domain-types.js';
9
19
 
10
- export interface Network {
11
- name: string;
12
- chainId: bigint;
13
- rpc: string[];
14
- contracts: NetworkContracts;
15
- indexer: string;
16
- broker: string;
17
- explorer?: string;
18
- }
20
+ export type { NetworkName };
@@ -1,3 +1,3 @@
1
1
  export * from './Signer.js';
2
2
  export * from './EthersSigner.js';
3
- export * from './PrivateKeySigner.js';
3
+ export * from './PrivateKeySigner.js';
package/src/types.ts CHANGED
@@ -22,7 +22,8 @@ export type TaskStatus =
22
22
  | 'submitted'
23
23
  | 'verified'
24
24
  | 'completed'
25
- | 'cancelled';
25
+ | 'cancelled'
26
+ | 'disputed';
26
27
 
27
28
  export interface TaskMetadata {
28
29
  category: string;
@@ -1,54 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { A as Address, H as Hex, T as TaskId, b as TxReceiptLike, e as TaskStatus } from './types-BOG5Ub1z.cjs';
3
-
4
- interface CreateTaskArgs {
5
- taskHash: Hex;
6
- token: Address;
7
- amount: bigint;
8
- category: string;
9
- locationZone: string;
10
- deadline: bigint;
11
- }
12
- interface OnChainTask {
13
- taskId: TaskId;
14
- agent: Address;
15
- worker: Address;
16
- token: Address;
17
- amount: bigint;
18
- taskHash: Hex;
19
- evidenceHash: Hex;
20
- status: TaskStatus;
21
- createdAt: Date;
22
- deadline: Date;
23
- }
24
- /**
25
- * Typed ethers v6 wrapper for the BlindEscrow contract. Every state-changing
26
- * method awaits one confirmation and returns a TxReceiptLike; every read
27
- * returns decoded values. Ethers errors are mapped to ChainError via
28
- * wrapChainError().
29
- */
30
- declare class BlindEscrowClient {
31
- readonly contract: ethers.Contract;
32
- readonly address: Address;
33
- constructor(address: Address, runner: ethers.ContractRunner);
34
- /** Create a task and return its id + receipt. Reads the TaskCreated event for the id. */
35
- createTask(args: CreateTaskArgs): Promise<{
36
- taskId: TaskId;
37
- receipt: TxReceiptLike;
38
- }>;
39
- assignWorker(taskId: TaskId, worker: Address): Promise<TxReceiptLike>;
40
- submitEvidence(taskId: TaskId, evidenceHash: Hex): Promise<TxReceiptLike>;
41
- completeVerification(taskId: TaskId, passed: boolean): Promise<TxReceiptLike>;
42
- cancelTask(taskId: TaskId): Promise<TxReceiptLike>;
43
- raiseDispute(taskId: TaskId): Promise<TxReceiptLike>;
44
- resolveDispute(taskId: TaskId, workerFavored: boolean): Promise<TxReceiptLike>;
45
- claimTimeout(taskId: TaskId): Promise<TxReceiptLike>;
46
- getTask(taskId: TaskId): Promise<OnChainTask>;
47
- isTaskExpired(taskId: TaskId): Promise<boolean>;
48
- nextTaskId(): Promise<TaskId>;
49
- feeBps(): Promise<bigint>;
50
- private sendTx;
51
- private extractTaskIdFromReceipt;
52
- }
53
-
54
- export { BlindEscrowClient as B, type CreateTaskArgs as C, type OnChainTask as O };
@@ -1,54 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { A as Address, H as Hex, T as TaskId, b as TxReceiptLike, e as TaskStatus } from './types-BOG5Ub1z.js';
3
-
4
- interface CreateTaskArgs {
5
- taskHash: Hex;
6
- token: Address;
7
- amount: bigint;
8
- category: string;
9
- locationZone: string;
10
- deadline: bigint;
11
- }
12
- interface OnChainTask {
13
- taskId: TaskId;
14
- agent: Address;
15
- worker: Address;
16
- token: Address;
17
- amount: bigint;
18
- taskHash: Hex;
19
- evidenceHash: Hex;
20
- status: TaskStatus;
21
- createdAt: Date;
22
- deadline: Date;
23
- }
24
- /**
25
- * Typed ethers v6 wrapper for the BlindEscrow contract. Every state-changing
26
- * method awaits one confirmation and returns a TxReceiptLike; every read
27
- * returns decoded values. Ethers errors are mapped to ChainError via
28
- * wrapChainError().
29
- */
30
- declare class BlindEscrowClient {
31
- readonly contract: ethers.Contract;
32
- readonly address: Address;
33
- constructor(address: Address, runner: ethers.ContractRunner);
34
- /** Create a task and return its id + receipt. Reads the TaskCreated event for the id. */
35
- createTask(args: CreateTaskArgs): Promise<{
36
- taskId: TaskId;
37
- receipt: TxReceiptLike;
38
- }>;
39
- assignWorker(taskId: TaskId, worker: Address): Promise<TxReceiptLike>;
40
- submitEvidence(taskId: TaskId, evidenceHash: Hex): Promise<TxReceiptLike>;
41
- completeVerification(taskId: TaskId, passed: boolean): Promise<TxReceiptLike>;
42
- cancelTask(taskId: TaskId): Promise<TxReceiptLike>;
43
- raiseDispute(taskId: TaskId): Promise<TxReceiptLike>;
44
- resolveDispute(taskId: TaskId, workerFavored: boolean): Promise<TxReceiptLike>;
45
- claimTimeout(taskId: TaskId): Promise<TxReceiptLike>;
46
- getTask(taskId: TaskId): Promise<OnChainTask>;
47
- isTaskExpired(taskId: TaskId): Promise<boolean>;
48
- nextTaskId(): Promise<TaskId>;
49
- feeBps(): Promise<bigint>;
50
- private sendTx;
51
- private extractTaskIdFromReceipt;
52
- }
53
-
54
- export { BlindEscrowClient as B, type CreateTaskArgs as C, type OnChainTask as O };