@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,113 @@
1
+ import type { A2ATaskState, AgentCapability, ExecutorProfile, Message } from '../types.js';
2
+ export interface WorkerRuntimeConfig {
3
+ apiKey: string;
4
+ apiBase?: string;
5
+ displayName: string;
6
+ capabilities: AgentCapability[];
7
+ executeTask: ExecuteTaskHandler;
8
+ existingPrivateKey?: string;
9
+ existingAddress?: string;
10
+ existingPublicKey?: string;
11
+ minReward?: string;
12
+ preferredCapabilities?: AgentCapability[];
13
+ browseIntervalMs?: number;
14
+ watchIntervalMs?: number;
15
+ maxConcurrentTasks?: number;
16
+ }
17
+ export type ExecuteTaskHandler = (ctx: TaskContext) => Promise<Record<string, unknown>>;
18
+ export interface TaskContext {
19
+ taskId: string;
20
+ task: A2ATaskState;
21
+ instructions: string;
22
+ }
23
+ export interface TaskExecutionInfo {
24
+ taskId: string;
25
+ status: 'bidding' | 'assigned' | 'working' | 'submitted' | 'completed' | 'failed';
26
+ task?: A2ATaskState;
27
+ error?: string;
28
+ startedAt: number;
29
+ }
30
+ export type WorkerRuntimeEvent = {
31
+ type: 'started';
32
+ } | {
33
+ type: 'stopped';
34
+ } | {
35
+ type: 'paused';
36
+ } | {
37
+ type: 'resumed';
38
+ } | {
39
+ type: 'registered';
40
+ profile: ExecutorProfile;
41
+ } | {
42
+ type: 'task_found';
43
+ taskId: string;
44
+ task: A2ATaskState;
45
+ } | {
46
+ type: 'task_bidded';
47
+ taskId: string;
48
+ } | {
49
+ type: 'task_assigned';
50
+ taskId: string;
51
+ } | {
52
+ type: 'task_accepted';
53
+ taskId: string;
54
+ } | {
55
+ type: 'task_working';
56
+ taskId: string;
57
+ } | {
58
+ type: 'task_executed';
59
+ taskId: string;
60
+ } | {
61
+ type: 'task_submitted';
62
+ taskId: string;
63
+ result: Record<string, unknown>;
64
+ } | {
65
+ type: 'task_failed';
66
+ taskId: string;
67
+ error: string;
68
+ } | {
69
+ type: 'message_received';
70
+ message: Message;
71
+ count: number;
72
+ } | {
73
+ type: 'browse_done';
74
+ found: number;
75
+ } | {
76
+ type: 'error';
77
+ error: string;
78
+ };
79
+ export declare class WorkerRuntime {
80
+ private bb;
81
+ private config;
82
+ private wallet?;
83
+ private profile?;
84
+ private running;
85
+ private paused;
86
+ private browseTimer?;
87
+ private watchTimers;
88
+ private executions;
89
+ private listeners;
90
+ constructor(config: WorkerRuntimeConfig);
91
+ get isRunning(): boolean;
92
+ get isPaused(): boolean;
93
+ get activeExecutions(): TaskExecutionInfo[];
94
+ /** Get own executor profile (available after start). */
95
+ get executorProfile(): ExecutorProfile | undefined;
96
+ /** Get own wallet info (available after start). */
97
+ get executorWallet(): {
98
+ address: string;
99
+ publicKey: string;
100
+ } | undefined;
101
+ on(listener: (event: WorkerRuntimeEvent) => void): () => void;
102
+ private emit;
103
+ start(): Promise<ExecutorProfile>;
104
+ stop(): void;
105
+ pause(): void;
106
+ resume(): void;
107
+ private startBrowseLoop;
108
+ private browse;
109
+ private watchForAssignment;
110
+ private executeTask;
111
+ private decodeWrappedKey;
112
+ private hexToBytes;
113
+ }
@@ -0,0 +1,248 @@
1
+ import { BlindMarket } from '../index.js';
2
+ import { eciesDecrypt, aesDecrypt } from '../crypto/index.js';
3
+ // ── Defaults ────────────────────────────────────────────────────────────────
4
+ const DEFAULTS = {
5
+ browseIntervalMs: 15_000,
6
+ watchIntervalMs: 5_000,
7
+ maxConcurrentTasks: 3,
8
+ };
9
+ // ── WorkerRuntime ───────────────────────────────────────────────────────────
10
+ export class WorkerRuntime {
11
+ bb;
12
+ config;
13
+ wallet;
14
+ profile;
15
+ running = false;
16
+ paused = false;
17
+ browseTimer;
18
+ watchTimers = new Map();
19
+ executions = new Map();
20
+ listeners = new Set();
21
+ constructor(config) {
22
+ this.config = { ...DEFAULTS, ...config };
23
+ this.bb = new BlindMarket({ apiKey: config.apiKey, apiBase: config.apiBase });
24
+ }
25
+ // ── Status ──────────────────────────────────────────────────────────────
26
+ get isRunning() {
27
+ return this.running;
28
+ }
29
+ get isPaused() {
30
+ return this.paused;
31
+ }
32
+ get activeExecutions() {
33
+ return [...this.executions.values()];
34
+ }
35
+ /** Get own executor profile (available after start). */
36
+ get executorProfile() {
37
+ return this.profile;
38
+ }
39
+ /** Get own wallet info (available after start). */
40
+ get executorWallet() {
41
+ return this.wallet;
42
+ }
43
+ // ── Events ──────────────────────────────────────────────────────────────
44
+ on(listener) {
45
+ this.listeners.add(listener);
46
+ return () => this.listeners.delete(listener);
47
+ }
48
+ emit(event) {
49
+ for (const l of this.listeners)
50
+ l(event);
51
+ }
52
+ // ── Lifecycle ───────────────────────────────────────────────────────────
53
+ async start() {
54
+ if (this.running)
55
+ return this.profile;
56
+ // 1. Register or restore executor
57
+ if (this.config.existingPrivateKey && this.config.existingAddress && this.config.existingPublicKey) {
58
+ this.wallet = {
59
+ address: this.config.existingAddress,
60
+ privateKey: this.config.existingPrivateKey,
61
+ publicKey: this.config.existingPublicKey,
62
+ };
63
+ // Fetch existing profile — backend identifies by API key
64
+ const result = await this.bb.getExecutorProfile();
65
+ this.profile = result.agent;
66
+ }
67
+ else {
68
+ const result = await this.bb.createAgent({
69
+ displayName: this.config.displayName,
70
+ capabilities: this.config.capabilities,
71
+ minReward: this.config.minReward,
72
+ preferredCapabilities: this.config.preferredCapabilities,
73
+ });
74
+ this.wallet = {
75
+ address: result.wallet.address,
76
+ privateKey: result.wallet.privateKey,
77
+ publicKey: result.wallet.publicKey,
78
+ };
79
+ this.profile = result.executor;
80
+ }
81
+ this.emit({ type: 'registered', profile: this.profile });
82
+ // 2. Start the browse loop
83
+ this.running = true;
84
+ this.startBrowseLoop();
85
+ this.emit({ type: 'started' });
86
+ return this.profile;
87
+ }
88
+ stop() {
89
+ this.running = false;
90
+ if (this.browseTimer) {
91
+ clearInterval(this.browseTimer);
92
+ this.browseTimer = undefined;
93
+ }
94
+ for (const t of this.watchTimers.values())
95
+ clearInterval(t);
96
+ this.watchTimers.clear();
97
+ this.emit({ type: 'stopped' });
98
+ }
99
+ pause() {
100
+ if (!this.running || this.paused)
101
+ return;
102
+ this.paused = true;
103
+ this.emit({ type: 'paused' });
104
+ }
105
+ resume() {
106
+ if (!this.running || !this.paused)
107
+ return;
108
+ this.paused = false;
109
+ this.emit({ type: 'resumed' });
110
+ // Immediately browse instead of waiting for next interval
111
+ this.browse();
112
+ }
113
+ // ── Browse loop ─────────────────────────────────────────────────────────
114
+ startBrowseLoop() {
115
+ const ms = this.config.browseIntervalMs;
116
+ this.browseTimer = setInterval(() => this.browse(), ms);
117
+ this.browse();
118
+ }
119
+ async browse() {
120
+ if (this.paused)
121
+ return;
122
+ try {
123
+ const active = this.activeExecutions;
124
+ const inFlight = active.filter(e => e.status === 'bidding' || e.status === 'working').length;
125
+ if (inFlight >= this.config.maxConcurrentTasks)
126
+ return;
127
+ const result = await this.bb.browseA2ATasks({
128
+ capabilities: this.config.capabilities,
129
+ });
130
+ this.emit({ type: 'browse_done', found: result.tasks.length });
131
+ for (const task of result.tasks) {
132
+ if (this.executions.has(task.taskId))
133
+ continue;
134
+ if (task.status !== 'open' && task.status !== 'bidding')
135
+ continue;
136
+ if (task.executorAddress && task.executorAddress !== this.wallet?.address)
137
+ continue;
138
+ this.executions.set(task.taskId, {
139
+ taskId: task.taskId,
140
+ status: 'bidding',
141
+ task,
142
+ startedAt: Date.now(),
143
+ });
144
+ this.emit({ type: 'task_found', taskId: task.taskId, task });
145
+ await this.bb.bidOnTask(task.taskId);
146
+ this.emit({ type: 'task_bidded', taskId: task.taskId });
147
+ this.watchForAssignment(task.taskId);
148
+ }
149
+ }
150
+ catch (err) {
151
+ this.emit({ type: 'error', error: `Browse failed: ${err}` });
152
+ }
153
+ }
154
+ // ── Assignment watching ─────────────────────────────────────────────────
155
+ watchForAssignment(taskId) {
156
+ if (!this.running)
157
+ return;
158
+ const ms = this.config.watchIntervalMs;
159
+ const timer = setInterval(async () => {
160
+ if (!this.running || this.paused)
161
+ return;
162
+ try {
163
+ const detail = await this.bb.getTask(taskId);
164
+ const a2a = detail.a2aState;
165
+ if (!a2a)
166
+ return;
167
+ if (a2a.status === 'assigned') {
168
+ clearInterval(timer);
169
+ this.watchTimers.delete(taskId);
170
+ this.emit({ type: 'task_assigned', taskId });
171
+ await this.executeTask(taskId, a2a);
172
+ }
173
+ }
174
+ catch {
175
+ // Retry next tick
176
+ }
177
+ }, ms);
178
+ this.watchTimers.set(taskId, timer);
179
+ }
180
+ // ── Task execution ──────────────────────────────────────────────────────
181
+ async executeTask(taskId, a2a) {
182
+ const exec = this.executions.get(taskId);
183
+ if (!exec)
184
+ return;
185
+ try {
186
+ exec.status = 'assigned';
187
+ // Accept task — get the ECIES-wrapped AES key
188
+ const acceptResult = await this.bb.acceptTask(taskId);
189
+ exec.task = acceptResult.task;
190
+ this.emit({ type: 'task_accepted', taskId });
191
+ // Get full task detail for the storage root hash
192
+ const detail = await this.bb.getTask(taskId);
193
+ const taskHash = detail.taskHash;
194
+ // Decrypt the wrapped key with the worker's private key
195
+ let instructions = '';
196
+ if (acceptResult.wrappedKey && taskHash) {
197
+ const wrappedBytes = this.decodeWrappedKey(acceptResult.wrappedKey);
198
+ const aesKey = await eciesDecrypt(wrappedBytes, this.wallet.privateKey);
199
+ // Download ciphertext from storage via REST API
200
+ const storageResult = await this.bb.downloadBlob(taskHash);
201
+ const ciphertext = this.hexToBytes(storageResult.data);
202
+ // AES decrypt to get plaintext instructions
203
+ const plaintext = await aesDecrypt(ciphertext, aesKey);
204
+ instructions = new TextDecoder().decode(plaintext);
205
+ }
206
+ exec.status = 'working';
207
+ this.emit({ type: 'task_working', taskId });
208
+ // Call the user-provided execution handler with decrypted instructions
209
+ const result = await this.config.executeTask({
210
+ taskId,
211
+ task: acceptResult.task,
212
+ instructions,
213
+ });
214
+ exec.status = 'submitted';
215
+ this.emit({ type: 'task_executed', taskId });
216
+ // Submit result
217
+ const submitResult = await this.bb.submitResult(taskId, result);
218
+ exec.status = 'completed';
219
+ this.emit({ type: 'task_submitted', taskId, result: submitResult });
220
+ }
221
+ catch (err) {
222
+ exec.status = 'failed';
223
+ exec.error = String(err);
224
+ this.emit({ type: 'task_failed', taskId, error: String(err) });
225
+ }
226
+ }
227
+ // ── Helpers ─────────────────────────────────────────────────────────────
228
+ decodeWrappedKey(wrappedKey) {
229
+ // Backend returns wrapped key as hex or base64 in a record
230
+ const hex = Object.values(wrappedKey)[0];
231
+ if (!hex)
232
+ throw new Error('Empty wrapped key');
233
+ const clean = hex.startsWith('0x') ? hex.slice(2) : hex;
234
+ const bytes = new Uint8Array(clean.length / 2);
235
+ for (let i = 0; i < bytes.length; i++) {
236
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
237
+ }
238
+ return bytes;
239
+ }
240
+ hexToBytes(hex) {
241
+ const clean = hex.startsWith('0x') ? hex.slice(2) : hex;
242
+ const bytes = new Uint8Array(clean.length / 2);
243
+ for (let i = 0; i < bytes.length; i++) {
244
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
245
+ }
246
+ return bytes;
247
+ }
248
+ }
@@ -0,0 +1 @@
1
+ export { WorkerRuntime, type WorkerRuntimeConfig, type ExecuteTaskHandler, type TaskContext, type TaskExecutionInfo, type WorkerRuntimeEvent, } from './WorkerRuntime.js';
@@ -0,0 +1 @@
1
+ export { WorkerRuntime, } from './WorkerRuntime.js';
package/dist/index.d.ts CHANGED
@@ -343,4 +343,11 @@ export { ApiError };
343
343
  export { tools, createBlindMarketTools, createTaskTools, createAgentManagementTools, createA2ATools, toLangChainTools, toVercelTools, toOpenAITools, toClaudeTools, } from './tools/index.js';
344
344
  export type { Tool, ToolKit, ToolDefinition } from './tools/types.js';
345
345
  export type { BlindMarketTools } from './tools/index.js';
346
+ export * from './executor/index.js';
346
347
  export * from './types.js';
348
+ export { EVMChainAdapter } from './chain/evm/index.js';
349
+ export { createChainAdapter } from './chain/createChainAdapter.js';
350
+ export type { CreateChainAdapterOptions } from './chain/createChainAdapter.js';
351
+ export type { IBlindMarketChain } from './chain/IBlindMarketChain.js';
352
+ export type { Network, EVMNetwork, BlockchainType, CreateTaskParams, DomainTask, DomainTaskMeta, DomainReputation, DomainTxReceipt, ChainSigner, } from './chain/domain-types.js';
353
+ export { isEVMNetwork } from './network/resolve.js';
package/dist/index.js CHANGED
@@ -130,7 +130,7 @@ export class BlindMarket {
130
130
  async submitEvidence(params) {
131
131
  return this.req('POST', '/api/v1/submissions/submit', params);
132
132
  }
133
- // ── Agent deployment & management ────────────────────────────────────────
133
+ // ── Agent deployment & management ─────────────────────────────────────────
134
134
  /**
135
135
  * Deploy a new agent. The backend generates a wallet, mints an INFT,
136
136
  * and returns the agent descriptor.
@@ -274,7 +274,7 @@ export class BlindMarket {
274
274
  * Trigger TEE / AI verification for a task.
275
275
  */
276
276
  async verify(params) {
277
- return this.req('POST', '/api/v1/verification/trigger', {
277
+ return this.req('POST', '/api/v1/verification/verify', {
278
278
  taskId: params.taskId,
279
279
  taskCategory: params.taskCategory,
280
280
  taskRequirements: params.taskRequirements,
@@ -307,7 +307,7 @@ export class BlindMarket {
307
307
  async downloadBlob(rootHash) {
308
308
  return this.req('GET', `/api/v1/storage/${rootHash}`);
309
309
  }
310
- // ── Messages ────────────────────────────────────────────────────────────
310
+ // ── Messages ─────────────────────────────────────────────────────────────
311
311
  /** Send a message to another user or agent. */
312
312
  async sendMessage(params) {
313
313
  return this.req('POST', '/api/v1/messages/send', params);
@@ -458,4 +458,9 @@ export class BlindMarket {
458
458
  export { ethers };
459
459
  export { ApiError };
460
460
  export { tools, createBlindMarketTools, createTaskTools, createAgentManagementTools, createA2ATools, toLangChainTools, toVercelTools, toOpenAITools, toClaudeTools, } from './tools/index.js';
461
+ export * from './executor/index.js';
461
462
  export * from './types.js';
463
+ // Chain abstraction layer
464
+ export { EVMChainAdapter } from './chain/evm/index.js';
465
+ export { createChainAdapter } from './chain/createChainAdapter.js';
466
+ export { isEVMNetwork } from './network/resolve.js';
@@ -1,14 +1,43 @@
1
1
  /**
2
2
  * Known-good network presets. Addresses pinned per SDK version so upgrading
3
3
  * the SDK cannot silently move contracts under a consumer.
4
- *
5
- * testnet = 0G Galileo (chainId 16602) — addresses from
6
- * contracts/deployments/0g-testnet.json (deployed 2026-04-15).
7
4
  */
5
+ export type NetworkName = 'testnet' | 'og-testnet' | 'og-mainnet';
8
6
  export declare const networks: {
7
+ readonly 'og-testnet': {
8
+ readonly name: "0g-galileo-testnet";
9
+ readonly chainType: "evm";
10
+ readonly chainId: 16602;
11
+ readonly rpc: ["https://evmrpc-testnet.0g.ai"];
12
+ readonly contracts: {
13
+ readonly escrow: "0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681";
14
+ readonly registry: "0xeE52d780A47F77E8a4a1cEb236e3C65A48FbD828";
15
+ readonly reputation: "0x4A6374Fae37E19E69ba43E7cf6994AC15F63256e";
16
+ readonly usdc: "0x317227efcA18D004E12CA8046AEf7E1597458F25";
17
+ };
18
+ readonly indexer: "https://indexer-storage-testnet-turbo.0g.ai";
19
+ readonly broker: "https://broker.testnet.0g.ai";
20
+ readonly explorer: "https://chainscan-galileo.0g.ai";
21
+ };
22
+ readonly 'og-mainnet': {
23
+ readonly name: "0g-mainnet";
24
+ readonly chainType: "evm";
25
+ readonly chainId: 16661;
26
+ readonly rpc: ["https://evmrpc.0g.ai"];
27
+ readonly contracts: {
28
+ readonly escrow: "0x3d0374963DaaD43e31d42373eb11156A8e8ce2Ff";
29
+ readonly registry: "0x9CCF9c196006B573FaA9C9c9CebDd1296dbd5cE0";
30
+ readonly reputation: "0x3af9232009C5da30AdA366B6E09849A040162A1a";
31
+ readonly usdc: "0x0000000000000000000000000000000000000000";
32
+ };
33
+ readonly indexer: "https://indexer-storage-turbo.0g.ai";
34
+ readonly broker: "https://broker.0g.ai";
35
+ readonly explorer: "https://chainscan.0g.ai";
36
+ };
9
37
  readonly testnet: {
10
38
  readonly name: "0g-galileo-testnet";
11
- readonly chainId: 16602n;
39
+ readonly chainType: "evm";
40
+ readonly chainId: 16602;
12
41
  readonly rpc: ["https://evmrpc-testnet.0g.ai"];
13
42
  readonly contracts: {
14
43
  readonly escrow: "0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681";
@@ -21,4 +50,3 @@ export declare const networks: {
21
50
  readonly explorer: "https://chainscan-galileo.0g.ai";
22
51
  };
23
52
  };
24
- export type NetworkName = keyof typeof networks;
@@ -1,14 +1,41 @@
1
- /**
2
- * Known-good network presets. Addresses pinned per SDK version so upgrading
3
- * the SDK cannot silently move contracts under a consumer.
4
- *
5
- * testnet = 0G Galileo (chainId 16602) — addresses from
6
- * contracts/deployments/0g-testnet.json (deployed 2026-04-15).
7
- */
8
1
  export const networks = {
2
+ // ── 0G EVM chains ─────────────────────────────────────────────────────
3
+ 'og-testnet': {
4
+ name: '0g-galileo-testnet',
5
+ chainType: 'evm',
6
+ chainId: 16602,
7
+ rpc: ['https://evmrpc-testnet.0g.ai'],
8
+ contracts: {
9
+ escrow: '0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681',
10
+ registry: '0xeE52d780A47F77E8a4a1cEb236e3C65A48FbD828',
11
+ reputation: '0x4A6374Fae37E19E69ba43E7cf6994AC15F63256e',
12
+ usdc: '0x317227efcA18D004E12CA8046AEf7E1597458F25',
13
+ },
14
+ indexer: 'https://indexer-storage-testnet-turbo.0g.ai',
15
+ broker: 'https://broker.testnet.0g.ai',
16
+ explorer: 'https://chainscan-galileo.0g.ai',
17
+ },
18
+ 'og-mainnet': {
19
+ name: '0g-mainnet',
20
+ chainType: 'evm',
21
+ chainId: 16661,
22
+ rpc: ['https://evmrpc.0g.ai'],
23
+ contracts: {
24
+ escrow: '0x3d0374963DaaD43e31d42373eb11156A8e8ce2Ff',
25
+ registry: '0x9CCF9c196006B573FaA9C9c9CebDd1296dbd5cE0',
26
+ reputation: '0x3af9232009C5da30AdA366B6E09849A040162A1a',
27
+ usdc: '0x0000000000000000000000000000000000000000',
28
+ },
29
+ indexer: 'https://indexer-storage-turbo.0g.ai',
30
+ broker: 'https://broker.0g.ai',
31
+ explorer: 'https://chainscan.0g.ai',
32
+ },
33
+ // ── Backward-compat alias ──────────────────────────────────────────────
34
+ // Kept so existing code referencing 'testnet' doesn't break.
9
35
  testnet: {
10
36
  name: '0g-galileo-testnet',
11
- chainId: 16602n,
37
+ chainType: 'evm',
38
+ chainId: 16602,
12
39
  rpc: ['https://evmrpc-testnet.0g.ai'],
13
40
  contracts: {
14
41
  escrow: '0xFd4F93F5A7BE144c405D1D8fbEC63Fb776207681',
@@ -1,7 +1,16 @@
1
1
  import { type NetworkName } from './presets.js';
2
- import type { Network } from './types.js';
2
+ import type { Network } from '../chain/domain-types.js';
3
3
  /**
4
- * Resolve a preset name or a literal Network object into the canonical
5
- * Network used throughout the SDK. Throws ConfigError for unknown names.
4
+ * Resolve a network preset name or a Network object to a canonical Network.
5
+ *
6
+ * When given a string, looks up the preset. When given a Network object,
7
+ * returns it as-is (pass-through for callers that already have a resolved
8
+ * network config).
6
9
  */
7
10
  export declare function resolveNetwork(arg: NetworkName | Network): Network;
11
+ /**
12
+ * Type guard: check if a Network is an EVM network.
13
+ */
14
+ export declare function isEVMNetwork(network: Network): network is Network & {
15
+ chainType: 'evm';
16
+ };
@@ -1,17 +1,25 @@
1
1
  import { ConfigError } from '../errors/index.js';
2
2
  import { networks } from './presets.js';
3
3
  /**
4
- * Resolve a preset name or a literal Network object into the canonical
5
- * Network used throughout the SDK. Throws ConfigError for unknown names.
4
+ * Resolve a network preset name or a Network object to a canonical Network.
5
+ *
6
+ * When given a string, looks up the preset. When given a Network object,
7
+ * returns it as-is (pass-through for callers that already have a resolved
8
+ * network config).
6
9
  */
7
10
  export function resolveNetwork(arg) {
8
11
  if (typeof arg === 'string') {
9
- const preset = networks[arg];
10
- if (!preset) {
11
- const known = Object.keys(networks).join(', ');
12
- throw new ConfigError('CONFIG/INVALID_NETWORK', `unknown network '${arg}' (known: ${known})`);
12
+ const net = networks[arg];
13
+ if (!net) {
14
+ throw new ConfigError('CONFIG/INVALID_NETWORK', `Unknown network: "${arg}". Known presets: ${Object.keys(networks).join(', ')}`);
13
15
  }
14
- return preset;
16
+ return net;
15
17
  }
16
18
  return arg;
17
19
  }
20
+ /**
21
+ * Type guard: check if a Network is an EVM network.
22
+ */
23
+ export function isEVMNetwork(network) {
24
+ return network.chainType === 'evm';
25
+ }
@@ -1,16 +1,3 @@
1
- import type { Address } from '../types.js';
2
- export interface NetworkContracts {
3
- escrow: Address;
4
- registry: Address;
5
- reputation: Address;
6
- usdc: Address;
7
- }
8
- export interface Network {
9
- name: string;
10
- chainId: bigint;
11
- rpc: string[];
12
- contracts: NetworkContracts;
13
- indexer: string;
14
- broker: string;
15
- explorer?: string;
16
- }
1
+ import type { NetworkName } from './presets.js';
2
+ export type { Network, EVMNetwork, NetworkBase, BlockchainType, CreateTaskParams, DomainTask, DomainTaskMeta, DomainReputation, DomainTxReceipt, ChainSigner, } from '../chain/domain-types.js';
3
+ export type { NetworkName };
package/dist/types.d.ts CHANGED
@@ -12,7 +12,7 @@ export interface Reward {
12
12
  token: Address | TokenSymbol;
13
13
  amount: bigint;
14
14
  }
15
- export type TaskStatus = 'funded' | 'assigned' | 'submitted' | 'verified' | 'completed' | 'cancelled';
15
+ export type TaskStatus = 'funded' | 'assigned' | 'submitted' | 'verified' | 'completed' | 'cancelled' | 'disputed';
16
16
  export interface TaskMetadata {
17
17
  category: string;
18
18
  locationZone: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blindmarket/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "BlindMarket SDK — deploy agents, assign workers, verify evidence",
5
5
  "author": "BlindMarket Team",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@ import type { Address, Hex, TaskId, TaskStatus, TxReceiptLike } from '../types.j
3
3
  import { BlindEscrowAbi } from './abi/index.js';
4
4
  import { wrapChainError } from './errors.js';
5
5
 
6
- const STATUS_BY_INDEX: TaskStatus[] = ['funded', 'assigned', 'submitted', 'verified', 'completed', 'cancelled'];
6
+ const STATUS_BY_INDEX: TaskStatus[] = ['funded', 'assigned', 'submitted', 'verified', 'completed', 'cancelled', 'disputed'];
7
7
 
8
8
  export interface CreateTaskArgs {
9
9
  taskHash: Hex;
@@ -23,6 +23,8 @@ export interface OnChainTask {
23
23
  taskHash: Hex;
24
24
  evidenceHash: Hex;
25
25
  status: TaskStatus;
26
+ category: string;
27
+ locationZone: string;
26
28
  createdAt: Date;
27
29
  deadline: Date;
28
30
  }
@@ -168,10 +170,15 @@ function toReceipt(rec: ethers.ContractTransactionReceipt | null): TxReceiptLike
168
170
  }
169
171
 
170
172
  function decodeTask(taskId: TaskId, raw: ethers.Result): OnChainTask {
171
- // Tuple order from BlindEscrow.getTask(): (agent, worker, token, amount, taskHash,
172
- // evidenceHash, status, createdAt, deadline) — verify against contracts/BlindEscrow.sol.
173
+ // Live Task struct (12 fields) from BlindEscrow.getTask(): agent, worker,
174
+ // token, amount, taskHash, evidenceHash, status, category, locationZone,
175
+ // createdAt, deadline, submissionAttempts. The old decode read createdAt from
176
+ // arr[7] (actually category) and deadline from arr[8] (actually locationZone),
177
+ // yielding Invalid Date and discarding category/locationZone.
173
178
  const arr = raw as unknown as unknown[];
174
179
  const statusIndex = Number(arr[6]);
180
+ const status = STATUS_BY_INDEX[statusIndex];
181
+ if (!status) throw new Error(`BlindEscrow.getTask returned unknown status index ${statusIndex}`);
175
182
  return {
176
183
  taskId,
177
184
  agent: arr[0] as Address,
@@ -180,8 +187,10 @@ function decodeTask(taskId: TaskId, raw: ethers.Result): OnChainTask {
180
187
  amount: BigInt(arr[3] as bigint | number),
181
188
  taskHash: arr[4] as Hex,
182
189
  evidenceHash: arr[5] as Hex,
183
- status: STATUS_BY_INDEX[statusIndex] ?? 'funded',
184
- createdAt: new Date(Number(arr[7] as bigint | number) * 1000),
185
- deadline: new Date(Number(arr[8] as bigint | number) * 1000),
190
+ status,
191
+ category: arr[7] as string,
192
+ locationZone: arr[8] as string,
193
+ createdAt: new Date(Number(arr[9] as bigint | number) * 1000),
194
+ deadline: new Date(Number(arr[10] as bigint | number) * 1000),
186
195
  };
187
196
  }